X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/7aa8cc3dc0df081350a7f9b4a30ef8490ee74fe0..7c474381d4dcc23b9fb4d3a2401971a9ef79c889:/l2tpns.c?ds=sidebyside diff --git a/l2tpns.c b/l2tpns.c index 8230945..f530955 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -73,6 +73,7 @@ time_t basetime = 0; // base clock char hostname[1000] = ""; // us. static int tunidx; // ifr_ifindex of tun device int nlseqnum = 0; // netlink sequence number +int min_initok_nlseqnum = 0; // minimun seq number for messages after init is ok static int syslog_log = 0; // are we logging to syslog static FILE *log_stream = 0; // file handle for direct logging (i.e. direct into file, not via syslog). uint32_t last_id = 0; // Unique ID for radius accounting @@ -418,16 +419,19 @@ void random_data(uint8_t *buf, int len) // via BGP if enabled, and stuffs it into the // 'sessionbyip' cache. // -// 'ip' and 'mask' must be in _host_ order. +// 'ip' must be in _host_ order. // -static void routeset(sessionidt s, in_addr_t ip, in_addr_t mask, in_addr_t gw, int add) +static void routeset(sessionidt s, in_addr_t ip, int prefixlen, in_addr_t gw, int add) { struct rtentry r; + in_addr_t mask; int i; - if (!mask) mask = 0xffffffff; + if (!prefixlen) prefixlen = 32; - ip &= mask; // Force the ip to be the first one in the route. + mask = 0xffffffff << (32 - prefixlen); + + ip &= mask; // Force the ip to be the first one in the route. memset(&r, 0, sizeof(r)); r.rt_dev = config->tundevice; @@ -440,11 +444,11 @@ static void routeset(sessionidt s, in_addr_t ip, in_addr_t mask, in_addr_t gw, i r.rt_flags = (RTF_UP | RTF_STATIC); if (gw) r.rt_flags |= RTF_GATEWAY; - else if (mask == 0xffffffff) + else if (prefixlen == 32) r.rt_flags |= RTF_HOST; - LOG(1, s, 0, "Route %s %s/%s%s%s\n", add ? "add" : "del", - fmtaddr(htonl(ip), 0), fmtaddr(htonl(mask), 1), + LOG(1, s, 0, "Route %s %s/%d%s%s\n", add ? "add" : "del", + fmtaddr(htonl(ip), 0), prefixlen, gw ? " via" : "", gw ? fmtaddr(htonl(gw), 2) : ""); if (ioctl(ifrfd, add ? SIOCADDRT : SIOCDELRT, (void *) &r) < 0) @@ -452,9 +456,9 @@ static void routeset(sessionidt s, in_addr_t ip, in_addr_t mask, in_addr_t gw, i #ifdef BGP if (add) - bgp_add_route(htonl(ip), htonl(mask)); + bgp_add_route(htonl(ip), prefixlen); else - bgp_del_route(htonl(ip), htonl(mask)); + bgp_del_route(htonl(ip), prefixlen); #endif /* BGP */ // Add/Remove the IPs to the 'sessionbyip' cache. @@ -470,7 +474,7 @@ static void routeset(sessionidt s, in_addr_t ip, in_addr_t mask, in_addr_t gw, i if (!add) // Are we deleting a route? s = 0; // Caching the session as '0' is the same as uncaching. - for (i = ip; (i&mask) == (ip&mask) ; ++i) + for (i = ip; i < ip+(1<<(32-prefixlen)) ; ++i) cache_ipmap(i, s); } } @@ -540,7 +544,7 @@ static void initnetlink(void) } } -static ssize_t netlink_send(struct nlmsghdr *nh, int want_ack) +static ssize_t netlink_send(struct nlmsghdr *nh) { struct sockaddr_nl nladdr; struct iovec iov; @@ -548,8 +552,6 @@ static ssize_t netlink_send(struct nlmsghdr *nh, int want_ack) nh->nlmsg_pid = getpid(); nh->nlmsg_seq = ++nlseqnum; - if (want_ack) - nh->nlmsg_flags |= NLM_F_ACK; // set kernel address memset(&nladdr, 0, sizeof(nladdr)); @@ -561,7 +563,7 @@ static ssize_t netlink_send(struct nlmsghdr *nh, int want_ack) return sendmsg(nlfd, &msg, 0); } -static ssize_t netlink_recv(char *buf, ssize_t len) +static ssize_t netlink_recv(void *buf, ssize_t len) { struct sockaddr_nl nladdr; struct iovec iov; @@ -577,47 +579,35 @@ static ssize_t netlink_recv(char *buf, ssize_t len) return recvmsg(nlfd, &msg, 0); } -static ssize_t netlink_check_ack(struct nlmsghdr *ack_nh, int msg_count) +/* adapted from iproute2 */ +void netlink_addattr(struct nlmsghdr *nh, int type, const void *data, int alen) { - ssize_t len; - uint32_t seqnum; - - // expect ack - for (; NLMSG_OK (ack_nh, len); ack_nh = NLMSG_NEXT (ack_nh, len)) - { - if (ack_nh->nlmsg_type == NLMSG_DONE) - return msg_count != 0 || seqnum != nlseqnum; - // 1 => lost an ack - - if (ack_nh->nlmsg_type == NLMSG_ERROR) - { - struct nlmsgerr *errmsg = NLMSG_DATA(ack_nh); - if (errmsg->error) - return errmsg->error; // got an error back - else - { - // ack received - --msg_count; - if (errmsg->msg.nlmsg_seq > seqnum); - seqnum = errmsg->msg.nlmsg_seq; - } - } - else - // unknown message - LOG(3, 0, 0, "Got an unknown netlink message: type %d\n", ack_nh->nlmsg_type); - } - - return 1; // malformed message?! + int len = RTA_LENGTH(alen); + struct rtattr *rta; + + rta = (struct rtattr *)(((void *)nh) + NLMSG_ALIGN(nh->nlmsg_len)); + rta->rta_type = type; + rta->rta_len = len; + memcpy(RTA_DATA(rta), data, alen); + nh->nlmsg_len = NLMSG_ALIGN(nh->nlmsg_len) + RTA_ALIGN(len); } +// messages corresponding to different phases seq number +static char *tun_nl_phase_msg[] = { + "initialized", + "getting tun interface index", + "setting tun interface parameters", + "setting tun IPv4 address", + "setting tun LL IPv6 address", + "setting tun global IPv6 address", +}; + // // Set up TUN interface static void inittun(void) { struct ifinfomsg ifinfo; struct ifreq ifr; - char buf[4096]; - struct nlmsghdr resp_nh; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; @@ -637,188 +627,164 @@ static void inittun(void) LOG(0, 0, 0, "Can't set tun interface: %s\n", strerror(errno)); exit(1); } - assert(strlen(ifr.ifr_name) < sizeof(config->tundevice)); - strncpy(config->tundevice, ifr.ifr_name, sizeof(config->tundevice) - 1); + assert(strlen(ifr.ifr_name) < sizeof(config->tundevice) - 1); + strncpy(config->tundevice, ifr.ifr_name, sizeof(config->tundevice)); { // get the interface index - ssize_t len; struct { struct nlmsghdr nh; struct ifinfomsg ifinfo __attribute__ ((aligned(NLMSG_ALIGNTO))); struct rtattr ifname_rta __attribute__ ((aligned(RTA_ALIGNTO))); char ifname[IFNAMSIZ]; } req; + char buf[4096]; + ssize_t len; + struct nlmsghdr *resp_nh; req.nh.nlmsg_type = RTM_GETLINK; req.nh.nlmsg_flags = NLM_F_REQUEST; + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifinfo)); req.ifinfo.ifi_family = AF_UNSPEC; // as the man says - req.ifname_rta.rta_len = RTA_LENGTH(strlen(config->tundevice)+1); - req.ifname_rta.rta_type = IFLA_IFNAME; - strncpy(req.ifname, config->tundevice, IFNAMSIZ-1); + netlink_addattr(&req.nh, IFLA_IFNAME, config->tundevice, strlen(config->tundevice)+1); - if(netlink_send(&req.nh, 0) < 0 || (len = netlink_recv(buf, sizeof(buf))) < 0) + if(netlink_send(&req.nh) < 0 || (len = netlink_recv(buf, sizeof(buf))) < 0) { LOG(0, 0, 0, "Error getting tun ifindex: %s\n", strerror(errno)); exit(1); } resp_nh = (struct nlmsghdr *)buf; - if (NLMSG_OK (resp_nh, len) && resp_nh.nlmsg_type == RTM_GETLINK) - { - memcpy(&ifinfo, NLMSG_DATA(resp_nh), sizeof(ifinfo)); - // got index - tunidx = ifinfo.ifi_index; - } - else + if (!NLMSG_OK (resp_nh, len)) { - LOG(0, 0, 0, "Malformed answer getting tun ifindex\n"); + LOG(0, 0, 0, "Malformed answer getting tun ifindex %ld\n", len); exit(1); } + + memcpy(&ifinfo, NLMSG_DATA(resp_nh), sizeof(ifinfo)); + // got index + tunidx = ifinfo.ifi_index; } { - ssize_t err; struct { // interface setting struct nlmsghdr nh; - struct ifinfomsg ifinfo __attribute__ ((aligned(NLMSG_ALIGNTO))); - struct rtattr txqlen_rta __attribute__ ((aligned(RTA_ALIGNTO))); - uint32_t txqlen; - struct rtattr mtu_rta __attribute__ ((aligned(RTA_ALIGNTO))); - uint32_t mtu; - - // IPv4 address - struct nlmsghdr addr_nh __attribute __ ((aligned(NLMSG_ALIGNTO))); - struct ifaddrmsg ifaddr __attribute __ ((aligned(NLMSG_ALIGNTO))); - struct rtattr addr_rta __attribute __ ((aligned(RTA_ALIGNTO))); - struct in_addr addr; - - // IPv6 LL address - struct nlmsghdr lladdr6_nh __attribute __ ((aligned(NLMSG_ALIGNTO))); - struct ifaddrmsg llifaddr6 __attribute __ ((aligned(NLMSG_ALIGNTO))); - struct rtattr lladdr6_rta __attribute __ ((aligned(RTA_ALIGNTO))); - struct in6_addr lladdr6; - - // IPv6 global address - struct nlmsghdr addr6_nh __attribute __ ((aligned(NLMSG_ALIGNTO))); - struct ifaddrmsg ifaddr6 __attribute __ ((aligned(NLMSG_ALIGNTO))); - struct rtattr addr6_rta __attribute __ ((aligned(RTA_ALIGNTO))); - struct in6_addr addr6; - - // end header - struct nlmsghdr end_nh __attribute __ ((aligned(NLMSG_ALIGNTO))); + union { + struct ifinfomsg ifinfo; + struct ifaddrmsg ifaddr; + } ifmsg __attribute__ ((aligned(NLMSG_ALIGNTO))); + char rtdata[32]; // 32 should be enough } req; - char buf[4096]; + uint32_t txqlen, mtu; + struct in_addr ip; memset(&req, 0, sizeof(req)); - req.nh.nlmsg_type = RTM_NEWLINK; - req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_MULTI; + req.nh.nlmsg_type = RTM_SETLINK; + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_MULTI; + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifmsg.ifinfo)); - req.ifinfo = ifinfo; - req.ifinfo.ifi_flags |= IFF_UP; // set interface up - req.ifinfo.ifi_change = IFF_UP; // only change this flag + req.ifmsg.ifinfo = ifinfo; + req.ifmsg.ifinfo.ifi_flags |= IFF_UP; // set interface up + req.ifmsg.ifinfo.ifi_change = IFF_UP; // only change this flag - req.txqlen_rta.rta_len = RTA_LENGTH(sizeof(req.txqlen)); - req.txqlen_rta.rta_type = IFLA_TXQLEN; /* Bump up the qlen to deal with bursts from the network */ - req.txqlen = 1000; - - req.mtu_rta.rta_len = RTA_LENGTH(sizeof(req.txqlen)); - req.mtu_rta.rta_type = IFLA_MTU; + txqlen = 1000; + netlink_addattr(&req.nh, IFLA_TXQLEN, &txqlen, sizeof(txqlen)); /* set MTU to modem MRU */ - req.mtu = MRU; + mtu = MRU; + netlink_addattr(&req.nh, IFLA_MTU, &mtu, sizeof(mtu)); - req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifinfo) - + req.txqlen_rla.rta_len - + req.mtu_rta.rta_len); + if (netlink_send(&req.nh) < 0) + goto senderror; - req.addr_nh.nlmsg_type = RTM_NEWADDR; - req.addr_nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_MULTI; + memset(&req, 0, sizeof(req)); + + req.nh.nlmsg_type = RTM_NEWADDR; + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_MULTI; + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifmsg.ifaddr)); - req.ifaddr.ifa_family = AF_INET; - req.ifaddr.ifa_prefixlen = 32; - req.ifaddr.ifa_index = ifinfo.ifi_index; + req.ifmsg.ifaddr.ifa_family = AF_INET; + req.ifmsg.ifaddr.ifa_prefixlen = 32; + req.ifmsg.ifaddr.ifa_index = ifinfo.ifi_index; - req.addr_rta.rta_len = RTA_LENGTH(sizeof(req.addr)); - req.addr_rta.rta_type = IFA_ADDRESS; - req.addr.s_addr = config->bind_address ? - config->bind_address : 0x01010101; // 1.1.1.1 + if (config->bind_address) + ip.s_addr = config->bind_address; + else + ip.s_addr = 0x01010101, // 1.1.1.1 + netlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip)); - req.addr_nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifaddr) - + req.addr_rta.rta_len); + if (netlink_send(&req.nh) < 0) + goto senderror; // Only setup IPv6 on the tun device if we have a configured prefix if (config->ipv6_prefix.s6_addr[0]) { - req.lladdr6_nh.nlmsg_type = RTM_NEWADDR; - req.lladdr6_nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_MULTI; + struct in6_addr ip6; + + memset(&req, 0, sizeof(req)); - req.llifaddr6.ifa_family = AF_INET6; - req.llifaddr6.ifa_prefixlen = 64; - req.llifaddr6.ifa_scope = RT_SCOPE_LINK; - req.llifaddr6.ifa_index = ifinfo.ifi_index; + req.nh.nlmsg_type = RTM_NEWADDR; + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_MULTI; + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifmsg.ifaddr)); + + req.ifmsg.ifaddr.ifa_family = AF_INET6; + req.ifmsg.ifaddr.ifa_prefixlen = 64; + req.ifmsg.ifaddr.ifa_scope = RT_SCOPE_LINK; + req.ifmsg.ifaddr.ifa_index = ifinfo.ifi_index; - req.lladdr6_rta.rta_len = RTA_LENGTH(sizeof(req.lladdr6)); - req.lladdr6_rta.rta_type = IFA_LOCAL; // Link local address is FE80::1 - memset(&req.lladdr6, 0, sizeof(req.lladdr6)); - req.lladdr6.s6_addr[0] = 0xFE; - req.lladdr6.s6_addr[1] = 0x80; - req.lladdr6.s6_addr[15] = 1; + memset(&ip6, 0, sizeof(ip6)); + ip6.s6_addr[0] = 0xFE; + ip6.s6_addr[1] = 0x80; + ip6.s6_addr[15] = 1; + netlink_addattr(&req.nh, IFA_LOCAL, &ip6, sizeof(ip6)); - req.lladdr6_nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifaddr) - + req.lladdr6_rta.rta_len); + if (netlink_send(&req.nh) < 0) + goto senderror; - req.addr6_nh.nlmsg_type = RTM_NEWADDR; - req.addr6_nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_MULTI; + memset(&req, 0, sizeof(req)); - req.ifaddr6.ifa_family = AF_INET6; - req.ifaddr6.ifa_prefixlen = 64; - req.ifaddr6.ifa_scope = RT_SCOPE_UNIVERSE; - req.ifaddr6.ifa_index = ifinfo.ifi_index; + req.nh.nlmsg_type = RTM_NEWADDR; + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_MULTI; + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifmsg.ifaddr)); - req.addr6_rta.rta_len = RTA_LENGTH(sizeof(req.addr6)); - req.addr6_rta.rta_type = IFA_LOCAL; - // Global address is prefix::1 - req.addr6 = config->ipv6_prefix; - req.addr6.s6_addr[15] = 1; + req.ifmsg.ifaddr.ifa_family = AF_INET6; + req.ifmsg.ifaddr.ifa_prefixlen = 64; + req.ifmsg.ifaddr.ifa_scope = RT_SCOPE_UNIVERSE; + req.ifmsg.ifaddr.ifa_index = ifinfo.ifi_index; - req.lladdr6_nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifaddr) - + req.lladdr6_rta.rta_len); + // Global address is prefix::1 + ip6 = config->ipv6_prefix; + ip6.s6_addr[15] = 1; + netlink_addattr(&req.nh, IFA_LOCAL, &ip6, sizeof(ip6)); - req.end_nh.nlmsg_type = NLMSG_DONE; - req.end_nh.nlmsg_len = NLMSG_LENGTH(0); - } - else - { - // we terminate at the beginning of IPv6 stuff - req.lladdr6_nh.nlmsg_type = NLMSG_DONE; - req.lladdr6_nh.nlmsg_len = NLMSG_LENGTH(0); + if (netlink_send(&req.nh) < 0) + goto senderror; } - if (netlink_send(&req.nh, 1) < 0) - LOG(0, 0, 0, "Error setting up tun device: %s\n", strerror(errno)); - exit(1); - } + memset(&req, 0, sizeof(req)); - if (netlink_recv(buf, sizeof(buf)) < 0) - { - LOG(0, 0, 0, "Error waiting ack for setting up tun device: %s\n", strerror(errno)); - exit(1); - } + req.nh.nlmsg_type = NLMSG_DONE; + req.nh.nlmsg_len = NLMSG_LENGTH(0); - resp_nh = (struct nlmsghdr *)buf; - if ((err = netlink_check_ack(resp_nh, 4))) - { - if (err < 0) - LOG(0, 0, 0, "Error while receiving tun device ack: %s\n", strerror(errno)); - else - LOG(0, 0, 0, "Error while receiving tun device ack\n", strerror(errno)); - exit(1); - } + if (netlink_send(&req.nh) < 0) + goto senderror; + + // if we get an error for seqnum < min_initok_nlseqnum, + // we must exit as initialization went wrong + if (config->ipv6_prefix.s6_addr[0]) + min_initok_nlseqnum = 5 + 1; // idx + if + addr + 2*addr6 + else + min_initok_nlseqnum = 3 + 1; // idx + if + addr } + + return; + +senderror: + LOG(0, 0, 0, "Error while setting up tun device: %s\n", strerror(errno)); + exit(1); } // set up UDP ports @@ -1964,11 +1930,11 @@ void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_e int routed = 0; for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++) { - if ((session[s].ip & session[s].route[r].mask) == - (session[s].route[r].ip & session[s].route[r].mask)) + if ((session[s].ip >> (32-session[s].route[r].prefixlen)) == + (session[s].route[r].ip >> (32-session[s].route[r].prefixlen))) routed++; - if (del_routes) routeset(s, session[s].route[r].ip, session[s].route[r].mask, 0, 0); + if (del_routes) routeset(s, session[s].route[r].ip, session[s].route[r].prefixlen, 0, 0); session[s].route[r].ip = 0; } @@ -3694,8 +3660,8 @@ static int still_busy(void) # include "fake_epoll.h" #endif -// the base set of fds polled: cli, cluster, tun, udp, control, dae -#define BASE_FDS 6 +// the base set of fds polled: cli, cluster, tun, udp, control, dae, netlink +#define BASE_FDS 7 // additional polled fds #ifdef BGP @@ -3719,8 +3685,8 @@ static void mainloop(void) exit(1); } - LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d\n", - clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd); + LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d\n", + clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd, nlfd); /* setup our fds to poll for input */ { @@ -3756,6 +3722,10 @@ static void mainloop(void) d[i].type = FD_TYPE_DAE; e.data.ptr = &d[i++]; epoll_ctl(epollfd, EPOLL_CTL_ADD, daefd, &e); + + d[i].type = FD_TYPE_NETLINK; + e.data.ptr = &d[i++]; + epoll_ctl(epollfd, EPOLL_CTL_ADD, nlfd, &e); } #ifdef BGP @@ -3892,6 +3862,32 @@ static void mainloop(void) break; #endif /* BGP */ + case FD_TYPE_NETLINK: + { + struct nlmsghdr *nh = (struct nlmsghdr *)buf; + s = netlink_recv(buf, sizeof(buf)); + if (nh->nlmsg_type == NLMSG_ERROR) + { + struct nlmsgerr *errmsg = NLMSG_DATA(nh); + if (errmsg->error) + { + if (errmsg->msg.nlmsg_seq < min_initok_nlseqnum) + { + LOG(0, 0, 0, "Got a fatal netlink error (while %s): %s\n", tun_nl_phase_msg[nh->nlmsg_seq], strerror(-errmsg->error)); + exit(1); + } + else + + LOG(0, 0, 0, "Got a netlink error: %s\n", strerror(-errmsg->error)); + } + // else it's a ack + } + else + LOG(1, 0, 0, "Got a unknown netlink message: type %d seq %d flags %d\n", nh->nlmsg_type, nh->nlmsg_seq, nh->nlmsg_flags); + n--; + break; + } + default: LOG(0, 0, 0, "Unexpected fd type returned from epoll_wait: %d\n", d->type); } @@ -4450,18 +4446,18 @@ static void fix_address_pool(int sid) // // Add a block of addresses to the IP pool to hand out. // -static void add_to_ip_pool(in_addr_t addr, in_addr_t mask) +static void add_to_ip_pool(in_addr_t addr, int prefixlen) { int i; - if (mask == 0) - mask = 0xffffffff; // Host route only. + if (prefixlen == 0) + prefixlen = 32; // Host route only. - addr &= mask; + addr &= 0xffffffff << (32 - prefixlen); if (ip_pool_size >= MAXIPPOOL) // Pool is full! return ; - for (i = addr ;(i & mask) == addr; ++i) + for (i = addr ; i < addr+(1<<(32-prefixlen)); ++i) { if ((i & 0xff) == 0 || (i&0xff) == 255) continue; // Skip 0 and broadcast addresses. @@ -4519,7 +4515,7 @@ static void initippool() { // It's a range int numbits = 0; - in_addr_t start = 0, mask = 0; + in_addr_t start = 0; LOG(2, 0, 0, "Adding IP address range %s\n", buf); *p++ = 0; @@ -4529,15 +4525,14 @@ static void initippool() continue; } start = ntohl(inet_addr(pool)); - mask = (in_addr_t) (pow(2, numbits) - 1) << (32 - numbits); // Add a static route for this pool - LOG(5, 0, 0, "Adding route for address pool %s/%u\n", - fmtaddr(htonl(start), 0), 32 + mask); + LOG(5, 0, 0, "Adding route for address pool %s/%d\n", + fmtaddr(htonl(start), 0), numbits); - routeset(0, start, mask, 0, 1); + routeset(0, start, numbits, 0, 1); - add_to_ip_pool(start, mask); + add_to_ip_pool(start, numbits); } else { @@ -4733,6 +4728,8 @@ int main(int argc, char *argv[]) } } + initnetlink(); + /* Set up the cluster communications port. */ if (cluster_init() < 0) exit(1); @@ -5184,11 +5181,11 @@ int sessionsetup(sessionidt s, tunnelidt t) // Add the route for this session. for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++) { - if ((session[s].ip & session[s].route[r].mask) == - (session[s].route[r].ip & session[s].route[r].mask)) + if ((session[s].ip >> (32-session[s].route[r].prefixlen)) == + (session[s].route[r].ip >> (32-session[s].route[r].prefixlen))) routed++; - routeset(s, session[s].route[r].ip, session[s].route[r].mask, 0, 1); + routeset(s, session[s].route[r].ip, session[s].route[r].prefixlen, 0, 1); } // Static IPs need to be routed if not already @@ -5259,7 +5256,7 @@ int load_session(sessionidt s, sessiont *new) for (i = 0; !newip && i < MAXROUTE && (session[s].route[i].ip || new->route[i].ip); i++) if (new->route[i].ip != session[s].route[i].ip || - new->route[i].mask != session[s].route[i].mask) + new->route[i].prefixlen != session[s].route[i].prefixlen) newip++; // needs update @@ -5270,11 +5267,11 @@ int load_session(sessionidt s, sessiont *new) // remove old routes... for (i = 0; i < MAXROUTE && session[s].route[i].ip; i++) { - if ((session[s].ip & session[s].route[i].mask) == - (session[s].route[i].ip & session[s].route[i].mask)) + if ((session[s].ip >> (32-session[s].route[i].prefixlen)) == + (session[s].route[i].ip >> (32-session[s].route[i].prefixlen))) routed++; - routeset(s, session[s].route[i].ip, session[s].route[i].mask, 0, 0); + routeset(s, session[s].route[i].ip, session[s].route[i].prefixlen, 0, 0); } // ...ip @@ -5293,11 +5290,11 @@ int load_session(sessionidt s, sessiont *new) // add new routes... for (i = 0; i < MAXROUTE && new->route[i].ip; i++) { - if ((new->ip & new->route[i].mask) == - (new->route[i].ip & new->route[i].mask)) + if ((new->ip >> (32-new->route[i].prefixlen)) == + (new->route[i].ip >> (32-new->route[i].prefixlen))) routed++; - routeset(s, new->route[i].ip, new->route[i].mask, 0, 1); + routeset(s, new->route[i].ip, new->route[i].prefixlen, 0, 1); } // ...ip