static int kaodv_netlink_receive_peer(unsigned char type, void *msg, unsigned int len) { int ret = 0; struct kaodv_rt_msg *m; struct kaodv_conf_msg *cm; struct expl_entry e; KAODV_DEBUG("Received msg: %s", kaodv_msg_type_to_str(type)); switch (type) { case KAODVM_ADDROUTE: if (len < sizeof(struct kaodv_rt_msg)) return -EINVAL; m = (struct kaodv_rt_msg *)msg; ret = kaodv_expl_get(m->dst, &e); if (ret > 0) { ret = kaodv_expl_update(m->dst, m->nhop, m->time, m->flags, m->ifindex); } else { ret = kaodv_expl_add(m->dst, m->nhop, m->time, m->flags, m->ifindex); } printk(KERN_DEBUG "kaodv: KAODVM_ADDROUTE!\n"); kaodv_queue_set_verdict(KAODV_QUEUE_SEND, m->dst); break; case KAODVM_DELROUTE: if (len < sizeof(struct kaodv_rt_msg)) return -EINVAL; m = (struct kaodv_rt_msg *)msg; kaodv_expl_del(m->dst); kaodv_queue_set_verdict(KAODV_QUEUE_DROP, m->dst); break; case KAODVM_NOROUTE_FOUND: if (len < sizeof(struct kaodv_rt_msg)) return -EINVAL; m = (struct kaodv_rt_msg *)msg; KAODV_DEBUG("No route found for %s", print_ip(m->dst)); kaodv_queue_set_verdict(KAODV_QUEUE_DROP, m->dst); break; case KAODVM_CONFIG: if (len < sizeof(struct kaodv_conf_msg)) return -EINVAL; cm = (struct kaodv_conf_msg *)msg; active_route_timeout = cm->active_route_timeout; qual_th = cm->qual_th; is_gateway = cm->is_gateway; break; default: printk("kaodv-netlink: Unknown message type\n"); ret = -EINVAL; } return ret; }
void kaodv_update_route_timeouts(int hooknum, const struct net_device *dev, struct iphdr *iph) { struct expl_entry e; struct in_addr bcaddr; int res; bcaddr.s_addr = 0; /* Stop compiler from complaining about * uninitialized bcaddr */ res = if_info_from_ifindex(NULL, &bcaddr, dev->ifindex); if (res < 0) return; if (hooknum == NF_INET_PRE_ROUTING) kaodv_netlink_send_rt_update_msg(PKT_INBOUND, iph->saddr, iph->daddr, dev->ifindex); else if (iph->daddr != INADDR_BROADCAST && iph->daddr != bcaddr.s_addr) kaodv_netlink_send_rt_update_msg(PKT_OUTBOUND, iph->saddr, iph->daddr, dev->ifindex); /* First update forward route and next hop */ if (kaodv_expl_get(iph->daddr, &e)) { kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags, dev->ifindex); if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e)) kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags, dev->ifindex); } /* Update reverse route */ if (kaodv_expl_get(iph->saddr, &e)) { kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags, dev->ifindex); if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e)) kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags, dev->ifindex); } }
static void kaodv_update_route_timeouts(int hooknum, const struct net_device *dev, struct iphdr *iph) { struct expl_entry e; struct netdev_info *netdi; netdi = netdev_info_from_ifindex(dev->ifindex); if (!netdi) return; if (hooknum == NF_IP_PRE_ROUTING) kaodv_netlink_send_rt_update_msg(PKT_INBOUND, iph->saddr, iph->daddr, dev->ifindex); else if (iph->daddr != INADDR_BROADCAST && iph->daddr != netdi->bc_addr) kaodv_netlink_send_rt_update_msg(PKT_OUTBOUND, iph->saddr, iph->daddr, dev->ifindex); /* First update forward route and next hop */ if (kaodv_expl_get(iph->daddr, &e)) { kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags); if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e)) kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags); } /* Update reverse route */ if (kaodv_expl_get(iph->saddr, &e)) { kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags); if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e)) kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT, e.flags); } }