Commit fc580b5a authored by Shashi Guruprasad's avatar Shashi Guruprasad

Updated nse.patch,tbnexthop.{cc,h} with all the recent nse changes.

tbnexthop.{cc,h} now contains setsockopts to install "ipfw fwd" rules.

<netinet/ip_fw.h> has changed from FBSD 4.3 to 4.5 . Because boss has 4.3,
compiling ipfw code on boss and running it on an experimental
node doesn't work. Therefore, I now have a cvs checked in local copy of
the 4.5 version of the file.

nseinput.tcl now finds the CPU cycle speed from /var/run/dmesg.boot and
passes the info to nse's RT scheduler which keeps track of real time
using the TSC. The same info can be obtained by PERFMON ioctls but the
kernel boot time measurement of the cpu cycle speed is more accurate than
what perfmon can report
parent e4c925e1
......@@ -20,6 +20,7 @@ msg:
@echo ""
@echo -n "WARNING! You must first do a \"make buildnse\" in $(SRCDIR) "
@echo "if $(SRCDIR)/nse is not built"
@echo "WARNING! It takes about 15 minutes for buildnse"
@echo ""
include $(TESTBED_SRCDIR)/GNUmakerules
......
This diff is collapsed.
#!/bin/sh
if [ ! -d /ns-allinone-2.1b9 ]; then
if [ ! -d ns-allinone-2.1b9 ]; then
echo "Downloading ns2.1b9 source ..."
fetch http://www.emulab.net/ns-allinone-2.1b9.tar.gz
tar xzf ns-allinone-2.1b9.tar.gz
patch -p0 < nse.patch
cd ns-allinone-2.1b9
./install
cp ns-2.1b9/nse ..
fi
cd ns-allinone-2.1b9
./install
cp ns-2.1b9/nse ..
This diff is collapsed.
......@@ -74,6 +74,53 @@ proc getmac {ipaddr} {
return ""
}
# This is temporary. Needs to be done from libsetup.pm
proc installipfwfwd {} {
set tmccroutelist [open /etc/testbed/tmcc.routelist r]
set routeliststr [read $tmccroutelist]
close $tmccroutelist
set ipfw /sbin/ipfw
set routelist [split $routeliststr "\n"]
foreach route $routelist {
set ret [scan $route "ROUTE NODE=%s SRC=%s DEST=%s DESTTYPE=%s DESTMASK=%s NEXTHOP=%s COST=%s" \
node src dst dsttype dstmask nexthop cost]
# we ensure that by expecting all 7 conversions in scan to happen for correct lines
# probably a ROUTERTYPE line if the conversion fails
if { $ret == 7 } {
exec $ipfw add fwd $nexthop ip from $src to $dst:$dstmask out
}
}
}
proc findcpuspeed {} {
set dmesgfd [open /var/run/dmesg.boot r]
set dmesg [read $dmesgfd]
close $dmesgfd
set regret [regexp {CPU:\D*(\d+\.?\d*)-([MmGg][Hh][zZ])} $dmesg matchstr speed mghz]
if { $regret == 1 } {
if { [regexp -nocase {mhz} $mghz] == 1 } {
return [expr $speed * 1000000]
} elseif { [regexp -nocase {ghz} $mghz] == 1 } {
return [expr $speed * 1000000000]
} else {
return -1
}
} else {
return -1
}
}
# call it after evaluating nseconfigs
# This will parse tmcc routelist and
# store a list of routes for all source nodes that are
# in this simulation
set tmccnseconfigs [open /etc/testbed/tmcc.nseconfigs r]
set nseconfig [read $tmccnseconfigs]
close $tmccnseconfigs
......@@ -93,6 +140,11 @@ if { [catch {eval $nseconfig} errMsg] == 1 } {
puts stderr "NSE: syntax error evaluating script: $errMsg"
}
# XXX: don't uncomment. causes incorrect behaviour
#if { $nsetrafgen_present == 1 || $simcode_present == 1 } {
# installipfwfwd
#}
# the name of the simulator instance variable might not
# always be 'ns', coming from the TB parser
set ns [Simulator instance]
......@@ -236,6 +288,7 @@ if { $simcode_present == 1 } {
if { [$nodeinst info vars nsenode_ipaddrlist] == {} } {
continue
}
set nodeinst_ipaddrlist [$nodeinst set nsenode_ipaddrlist]
foreach nodeinst_ipaddr $nodeinst_ipaddrlist {
set iface [getif $nodeinst_ipaddr]
......@@ -257,6 +310,22 @@ if { $simcode_present == 1 } {
# associate the 2 network objects in the IPTap object
$iptap($i) network-outgoing $ipnet
$iptap($i) network-incoming $bpf_ip($i)
if { [$nodeinst info vars routes] != {} } {
set routelist [split [$nodeinst set routes] "\n"]
foreach route $routelist {
scan $route "DST=%s DST_MASK=%s NEXTHOP=%s" dstip dstmask nexthop
$iptap($i) addroute $dstip $nexthop
# We dont really consider the case where different routes
# have different masks. A complete longest prefix match
# implementation that is also efficient for nse may
# have to be done in the future
}
}
# The emulab default netmask
$iptap($i) ipmask "255.255.255.0"
$ns attach-agent $nodeinst $iptap($i)
......@@ -289,4 +358,9 @@ if { $objnamelist != {} } {
[$ns set scheduler_] tbevent-sink $evsink
}
set cpuspeed [findcpuspeed]
if { $cpuspeed != -1 } {
[$ns set scheduler_] cpuspeed $cpuspeed
}
$ns run
......@@ -74,6 +74,53 @@ proc getmac {ipaddr} {
return ""
}
# This is temporary. Needs to be done from libsetup.pm
proc installipfwfwd {} {
set tmccroutelist [open /etc/testbed/tmcc.routelist r]
set routeliststr [read $tmccroutelist]
close $tmccroutelist
set ipfw /sbin/ipfw
set routelist [split $routeliststr "\n"]
foreach route $routelist {
set ret [scan $route "ROUTE NODE=%s SRC=%s DEST=%s DESTTYPE=%s DESTMASK=%s NEXTHOP=%s COST=%s" \
node src dst dsttype dstmask nexthop cost]
# we ensure that by expecting all 7 conversions in scan to happen for correct lines
# probably a ROUTERTYPE line if the conversion fails
if { $ret == 7 } {
exec $ipfw add fwd $nexthop ip from $src to $dst:$dstmask out
}
}
}
proc findcpuspeed {} {
set dmesgfd [open /var/run/dmesg.boot r]
set dmesg [read $dmesgfd]
close $dmesgfd
set regret [regexp {CPU:\D*(\d+\.?\d*)-([MmGg][Hh][zZ])} $dmesg matchstr speed mghz]
if { $regret == 1 } {
if { [regexp -nocase {mhz} $mghz] == 1 } {
return [expr $speed * 1000000]
} elseif { [regexp -nocase {ghz} $mghz] == 1 } {
return [expr $speed * 1000000000]
} else {
return -1
}
} else {
return -1
}
}
# call it after evaluating nseconfigs
# This will parse tmcc routelist and
# store a list of routes for all source nodes that are
# in this simulation
set tmccnseconfigs [open /etc/testbed/tmcc.nseconfigs r]
set nseconfig [read $tmccnseconfigs]
close $tmccnseconfigs
......@@ -93,6 +140,11 @@ if { [catch {eval $nseconfig} errMsg] == 1 } {
puts stderr "NSE: syntax error evaluating script: $errMsg"
}
# XXX: don't uncomment. causes incorrect behaviour
#if { $nsetrafgen_present == 1 || $simcode_present == 1 } {
# installipfwfwd
#}
# the name of the simulator instance variable might not
# always be 'ns', coming from the TB parser
set ns [Simulator instance]
......@@ -236,6 +288,7 @@ if { $simcode_present == 1 } {
if { [$nodeinst info vars nsenode_ipaddrlist] == {} } {
continue
}
set nodeinst_ipaddrlist [$nodeinst set nsenode_ipaddrlist]
foreach nodeinst_ipaddr $nodeinst_ipaddrlist {
set iface [getif $nodeinst_ipaddr]
......@@ -257,6 +310,22 @@ if { $simcode_present == 1 } {
# associate the 2 network objects in the IPTap object
$iptap($i) network-outgoing $ipnet
$iptap($i) network-incoming $bpf_ip($i)
if { [$nodeinst info vars routes] != {} } {
set routelist [split [$nodeinst set routes] "\n"]
foreach route $routelist {
scan $route "DST=%s DST_MASK=%s NEXTHOP=%s" dstip dstmask nexthop
$iptap($i) addroute $dstip $nexthop
# We dont really consider the case where different routes
# have different masks. A complete longest prefix match
# implementation that is also efficient for nse may
# have to be done in the future
}
}
# The emulab default netmask
$iptap($i) ipmask "255.255.255.0"
$ns attach-agent $nodeinst $iptap($i)
......@@ -289,4 +358,9 @@ if { $objnamelist != {} } {
[$ns set scheduler_] tbevent-sink $evsink
}
set cpuspeed [findcpuspeed]
if { $cpuspeed != -1 } {
[$ns set scheduler_] cpuspeed $cpuspeed
}
$ns run
......@@ -13,6 +13,15 @@
#include <netinet/in.h>
#include <net/if_dl.h>
#include <unistd.h>
#include <errno.h>
/*#include <netinet/ip_fw.h> */
/* ipfw data structures have changed between FBSD 4.3 and FBSD 4.5 .
boss has the former but the experimental nodes run the latter.
Therefore use a local version of ip_fw.h which is also in cvs */
#include "ip_fw.h"
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "tbnexthop.h"
static int sockfd;
......@@ -108,6 +117,67 @@ get_nexthop_if(struct in_addr addr)
return 0;
}
/* Does a
ipfw add fwd <nexthop> ip from <src> to <dst>:<dstmask> [out]
and returns the number of the added rule
*/
static int ipfw_sock = -1;
int
ipfw_addfwd(struct in_addr nexthop, struct in_addr src, struct in_addr dst,
struct in_addr dstmask, bool out) {
struct ip_fw rule;
if( ipfw_sock == -1 ) {
ipfw_sock = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
if( ipfw_sock < 0 ) {
fprintf(stderr, "can't create raw socket: %s\n", strerror(errno));
return(-1);
}
}
memset(&rule, 0, sizeof rule);
/* rule.fw_flg |= IP_FW_F_FWD | IP_FW_F_DMSK;*/
rule.fw_flg |= IP_FW_F_FWD;
rule.fw_prot |= IPPROTO_IP;
/* filling next hop information */
rule.fw_fwd_ip.sin_len = sizeof(struct sockaddr_in);
rule.fw_fwd_ip.sin_family = AF_INET;
rule.fw_fwd_ip.sin_port = 0;
rule.fw_fwd_ip.sin_addr = nexthop;
// printf( "nexthop = %s\n", inet_ntoa(nexthop));
rule.fw_src = src;
//printf( "src = %s\n", inet_ntoa(src));
rule.fw_smsk.s_addr = ~0;
//printf( "smsk = %s\n", inet_ntoa(rule.fw_smsk));
rule.fw_dst = dst;
//printf( "dst = %s\n", inet_ntoa(dst));
rule.fw_dmsk = dstmask;
//printf( "dmsk = %s\n", inet_ntoa(rule.fw_dmsk));
if( out ) {
rule.fw_flg |= IP_FW_F_OUT;
}
/* getsockopt and setsockopt do the same thing for ipfw rules
except that in the former, the rule is copied back. Since
we need the rule number that ipfirewall chose, we use
getsockopt() */
socklen_t i = sizeof(rule);
if (getsockopt(ipfw_sock, IPPROTO_IP, IP_FW_ADD, &rule, &i) == -1) {
fprintf(stderr, "getsockopt(IP_FW_ADD): %s\n", strerror(errno));
return(-1);
}
return(rule.fw_number);
}
#ifdef TBNEXTHOP_TESTME
int
main(int argc, char **argv)
......@@ -136,3 +206,41 @@ main(int argc, char **argv)
exit(0);
}
#endif
#ifdef IPFW_ADDFWD_TESTME
int
main(int argc, char *argv[])
{
struct in_addr src, dst, mask, nexthop;
int rulenum;
if (argc < 5) {
fprintf(stderr, "usage: %s src dst mask nexthop\n", argv[0]);
exit(2);
}
printf("argc = %d\n", argc );
if (inet_aton(argv[1], &src) == 0) {
fprintf(stderr, "bad src IP address: %s\n", argv[1]);
exit(2);
}
if (inet_aton(argv[2], &dst) == 0) {
fprintf(stderr, "bad dst IP address: %s\n", argv[2]);
exit(3);
}
if (inet_aton(argv[3], &mask) == 0) {
fprintf(stderr, "bad IP mask: %s\n", argv[3]);
exit(4);
}
if (inet_aton(argv[4], &nexthop) == 0) {
fprintf(stderr, "bad nexthop IP address: %s\n", argv[4]);
exit(5);
}
rulenum = ipfw_addfwd(nexthop, src, dst, mask, true);
printf("rulenum = %d\n", rulenum);
exit(0);
}
#endif
......@@ -8,8 +8,13 @@
#define TBNEXTHOP
#include <netinet/in.h>
#include <sys/types.h>
uint16_t
get_nexthop_if(struct in_addr addr);
int
ipfw_addfwd(struct in_addr nexthop, struct in_addr src, struct in_addr dst,
struct in_addr dstmask, bool out);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment