if (gotargs != 3) return 1;
info("Read config from '%s'\r\n", file);
- info("Proxying neighbor advertisements to %s\r\n", c->proxy_dev);
+ if (strncmp(c->proxy_dev, "lo", 3) != 0) {
+ info("Proxying neighbor advertisements to %s\r\n", c->proxy_dev);
+ }
info("Using channel %i\r\n", c->channel);
info("Retries: %i\r\n", c->retries);
lastconfig = c;
#include <includes.h>
#include <radvd.h>
+
+uint16_t routing_get_seqno();
+
+#define ICMP_EXT_TYPE_BEACON 17
+
+/* SDH : copied from ICMP.h */
+struct AdvMetric {
+ uint8_t type;
+ uint8_t length;
+ uint16_t metric;
+ uint16_t seqno;
+ uint8_t pad[2];
+};
+
+
void
send_ra(int sock, struct Interface *iface, struct in6_addr *dest)
{
memcpy(buff + len, &ha_info, sizeof(ha_info));
len += sizeof(ha_info);
}
+
+ {
+ /* add routing metric */
+ struct AdvMetric metric;
+ metric.type = ICMP_EXT_TYPE_BEACON;
+ metric.length = 1;
+ metric.metric = htons(0);
+ metric.seqno = htons(routing_get_seqno());
+ memset(metric.pad, 0, sizeof(metric.pad));
+
+ memcpy(buff + len, &metric, sizeof(struct AdvMetric));
+ len += sizeof(struct AdvMetric);
+ }
iov.iov_len = len;
iov.iov_base = (caddr_t) buff;
set_timer(&iface->tm, next);
}
+void radvd_reset_adverts(void) {
+ if (iface->AdvSendAdvert) {
+ /* send an initial advertisement */
+ send_ra(sock, iface, NULL);
+
+ iface->init_racount = 0;
+
+ set_timer(&iface->tm,
+ min(MAX_INITIAL_RTR_ADVERT_INTERVAL,
+ iface->MaxRtrAdvInterval));
+ }
+}
+
void radvd_kickoff_adverts(void) {
init_timer(&iface->tm, radvd_timer_handler, (void *) iface);
#include "netlink.h"
static ieee154_saddr_t my_short_addr;
+static uint16_t current_seqno;
extern struct in6_addr __my_address;
char proxy_dev[IFNAMSIZ], tun_dev[IFNAMSIZ];
fclose(fd);
}
+ if ((fd = fopen("/var/run/ip-driver.seq", "r")) != NULL) {
+ if (fscanf(fd, "%hi\n", ¤t_seqno) != 1) {
+ current_seqno = 0;
+ }
+ fclose(fd);
+ }
+
return (mcast_sock >= 0) ? 0 : -1;
}
return ret;
}
+
+uint16_t routing_get_seqno() {
+ return current_seqno;
+}
+
+uint16_t routing_incr_seqno() {
+ FILE *fd;
+ ++current_seqno;
+ if ((fd = fopen("/var/run/ip-driver.seq", "w")) != NULL) {
+ fprintf(fd, "%hi\n", current_seqno);
+ fclose(fd);
+ }
+ return current_seqno;
+}
*/
int routing_add_report(node_id_t reporter, struct tlv_hdr *tlv);
+
+uint16_t routing_get_seqno();
+
+uint16_t routing_incr_seqno();
#endif
int radvd_init(char *ifname, struct config *c);
void radvd_process();
+void radvd_reset_adverts(void);
#ifndef SF_SRC
serial_source ser_src;
struct generic_header *g_hdr;
if (log_getlevel() > LOGLVL_DEBUG) return;
- printf(" nxthdr: 0x%x hlim: 0x%x\n", msg->hdr.nxt_hdr, msg->hdr.hlim);
+ printf(" nxthdr: 0x%x hlim: 0x%x plen: %i\n", msg->hdr.nxt_hdr, msg->hdr.hlim, ntohs(msg->hdr.plen));
printf(" src: ");
for (i = 0; i < 16; i++) printf("0x%x ", msg->hdr.ip6_src.s6_addr[i]);
printf("\n");
VTY_printf(" links : print link detail\r\n");
VTY_printf(" routes : print routes\r\n");
VTY_printf(" newroutes : recalculate routes\r\n");
+ VTY_printf(" rebuild : initiate a DAG recomputation\r\n");
VTY_printf(" controller <n> : add a new controller\r\n");
#ifdef CENTRALIZED_ROUTING
VTY_printf(" install <HOP | SRC> <n1> <n2> [reverse]: install a route between n1 and n2\r\n");
VTY_flush();
}
+void sh_incr_seqno(int fd, int argc, char **argv) {
+ VTY_HEAD;
+ VTY_printf("DAG seqno now %i\r\n", routing_incr_seqno());
+ radvd_reset_adverts();
+
+ VTY_flush();
+}
+
struct vty_cmd vty_cmd_list[] = {{"help", print_help},
{"stats", print_stats},
{"links", nw_print_links},
{"log", sh_loglevel},
{"dot", sh_dotfile},
{"chan", sh_chan},
+ {"rebuild", sh_incr_seqno},
#ifdef CENTRALIZED_ROUTING
{"install", sh_install},
{"uninstall", sh_uninstall},
}
usecs_remain -= (KEEPALIVE_TIMEOUT - tv.tv_usec);
if (usecs_remain <= 0) {
- if (keepalive_needed) {
+ if (keepalive_needed && !opt_listenonly) {
configure_setparms(&driver_config, CONFIG_KEEPALIVE);
} else keepalive_needed = 1;
break;
case 'l':
opt_listenonly = 1;
+ info("Listen Only: will not attach to interface device\n");
break;
case 't':
info("TrackFlows: will insert flow id on outgoing packets\n");
}
}
- if (argc - optind != 2) {
+ if (argc - optind != 2 && !opt_listenonly) {
#ifndef SF_SRC
- fatal("usage: %s [-c config] [-n] <device> <rate>\n", argv[0]);
+ fatal("usage: %s [-c config] [-l] <device> <rate>\n", argv[0]);
#else
fatal("usage: %s [-c config] <host> <port>\n", argv[0]);
#endif
}
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
- ifr6.ifr6_prefixlen = 128;
+ ifr6.ifr6_prefixlen = 64;//128;
if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
log_fatal_perror("SIOCSIFADDR (global)");
return -1;
void adjustPlen(struct ip6_hdr *ip, unpack_info_t *u_info) {
uint16_t adjust_amt = u_info->payload_offset;
- /*
- switch (u_info->nxt_hdr) {
+
+ switch (ip->nxt_hdr) {
case IANA_UDP:
adjust_amt -= sizeof(struct udp_hdr); break;
}
- */
ip->plen = htons(ntohs(ip->plen) - adjust_amt);
}
dest += sizeof(struct udp_hdr);
u_info->nxt_hdr = IANA_UDP;
- // u_info->payload_offset += sizeof(struct udp_hdr);
+ u_info->payload_offset += sizeof(struct udp_hdr);
u_info->transport_ptr = (uint8_t *)udp;
} else {
nx_uint8_t type;
nx_uint8_t length;
nx_uint16_t metric;
- nx_uint8_t pad[4];
+ nx_uint16_t seqno;
+ nx_uint8_t pad[2];
} rqual_t;
struct icmp_stats {
icmp_statistics_t stats;
uint32_t solicitation_period;
uint32_t advertisement_period;
+ uint16_t nd_seqno = 0;
uint16_t ping_seq, ping_n, ping_rcv, ping_ident;
struct in6_addr ping_dest;
}
command void ICMP.sendAdvertisements() {
+
+
uint16_t jitter = (call Random.rand16()) % TRICKLE_JITTER;
CHECK_NODE_ID;
if (call Advertisement.isRunning()) return;
radv_t *r = (radv_t *)payload;
pfx_t *pfx = (pfx_t *)(r->options);
- uint16_t cost = 0;
rqual_t *beacon = (rqual_t *)(pfx + 1);
if (len > sizeof(radv_t) + sizeof(pfx_t) &&
beacon->type == ICMP_EXT_TYPE_BEACON) {
- cost = beacon->metric;
+
+ if (beacon->seqno > nd_seqno || (nd_seqno > 0 && beacon->seqno == 0)) {
+ call IPRouting.reset();
+ }
+
+ nd_seqno = beacon->seqno;
+ call IPRouting.reportAdvertisement(meta->sender, r->hlim,
+ meta->lqi, beacon->metric);
+
+
+
dbg("ICMPResponder", " * beacon cost: 0x%x\n", cost);
- } else
+ } else {
dbg("ICMPResponder", " * no beacon cost\n");
-
- call IPRouting.reportAdvertisement(meta->sender, r->hlim,
- meta->lqi, cost);
+ }
if (pfx->type != ICMP_EXT_TYPE_PREFIX) return;
packed_lowmsg_t lowmsg;
printfUART("p1: %p p2: %p\n", msg_payload, call Packet.getPayload(msg, 0));
+ printfUART("l1: %i l2: %i\n", len, call Packet.payloadLength(msg));
+
// set up the ip message structaddFragment
lowmsg.data = msg_payload;
lowmsg.len = len;
uint8_t last_hops;
uint16_t reportSeqno;
- uint8_t num_low_neigh;
-
bool soliciting;
// pointer into the neighbor table of the current entry that is our
}
- event void Boot.booted() {
+ command void IPRouting.reset() {
int i;
+ printfUART("ROUTING RESET\n");
for (i = 0; i < N_NEIGH; i++) {
neigh_table[i].flags = 0;
#endif
// current_epoch = 0;
- soliciting = FALSE;
+ if (!soliciting) {
+ call ICMP.sendSolicitations();
+ soliciting = TRUE;
+ }
//reRouting = FALSE;
default_route_failures = 0;
default_route = &neigh_table[0];
// associated from us when it gets the first packet.
last_qual = 0xffff;
last_hops = 0xff;
- num_low_neigh = 0;
+
+ traffic_sent = FALSE;
+ restartTrafficGen();
+ }
+
+ event void Boot.booted() {
+ call IPRouting.reset();
reportSeqno = call Random.rand16();
call Statistics.clear();
call SortTimer.startPeriodic(1024L * 60);
- traffic_sent = FALSE;
- restartTrafficGen();
}
command bool IPRouting.isForMe(struct ip6_hdr *hdr) {
//bool recount = FALSE;
struct neigh_entry *neigh_slot = NULL;
dbg("IPRouting", "report adv: 0x%x 0x%x 0x%x 0x%x\n", neigh, hops, lqi, cost);
- dbg("IPRouting", "my Cost: 0x%x, num_low_neigh: 0x%x, N_LOW_NEIGH: 0x%x\n",
- getMetric(&(neigh_table[0])), num_low_neigh, N_LOW_NEIGH);
+ dbg("IPRouting", "my Cost: 0x%x\n", getMetric(&(neigh_table[0])));
// If neighbor does not exist in table
if ((neigh_slot = getNeighEntry(neigh)) == NULL) {
printfUART("rx cksum: %x calc: %x\n", rx_cksum, my_cksum);
if (rx_cksum != my_cksum) {
BLIP_STATS_INCR(cksum);
- return;
+ // return;
}
}
command struct ip6_route *insertRoutingHeader(struct split_ip_msg *msg);
+ command void reset();
+
#ifdef CENTRALIZED_ROUTING
// command error_t installFlowEntry(struct rinstall_header* rih, bool isMine);