diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2016-03-13 00:20:49 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2016-03-13 11:33:14 +0300 |
commit | c45b00d84de954d7f27fc7dce2909fab198cc298 (patch) | |
tree | a1cb5306b63a5e43282ce6c193d6529c3a6c1e62 /accel-pppd/ctrl/ipoe | |
parent | d01f9f7161eb5d46a656fd1cff1baf41a65d769f (diff) | |
download | accel-ppp-c45b00d84de954d7f27fc7dce2909fab198cc298.tar.gz accel-ppp-c45b00d84de954d7f27fc7dce2909fab198cc298.zip |
ipoe: many many changes
Diffstat (limited to 'accel-pppd/ctrl/ipoe')
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 241 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 13 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe_netlink.c | 128 |
3 files changed, 70 insertions, 312 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index e7f1ca50..55bedac8 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -43,15 +43,8 @@ #define USERNAME_IFNAME 1 #define USERNAME_LUA 2 -#define MODE_L2 0 -#define MODE_L3 1 - -struct ifaddr { - struct list_head entry; - in_addr_t addr; - int mask; - int refs; -}; +#define MODE_L2 2 +#define MODE_L3 3 struct iplink_arg { pcre *re; @@ -510,7 +503,8 @@ static int ipoe_create_interface(struct ipoe_session *ses) mempool_free(uc); } else { pthread_mutex_unlock(&uc_lock); - ses->ifindex = ipoe_nl_create(0, 0, ses->serv->opt_mode == MODE_L2 ? ses->serv->ifname : NULL, ses->hwaddr); + + ses->ifindex = ipoe_nl_create(ses->serv->ifindex); if (ses->ifindex == -1) { log_ppp_error("ipoe: failed to create interface\n"); ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 1); @@ -530,7 +524,6 @@ static int ipoe_create_interface(struct ipoe_session *ses) strncpy(ses->ses.ifname, ifr.ifr_name, AP_IFNAME_LEN); ses->ses.ifindex = ses->ifindex; ses->ses.unit_idx = ses->ifindex; - ses->ctrl.dont_ifcfg = !conf_ip_unnumbered; log_ppp_info2("create interface %s parent %s\n", ifr.ifr_name, ses->serv->ifname); @@ -802,115 +795,39 @@ static void __ipoe_session_start(struct ipoe_session *ses) } } -static void ipoe_serv_add_addr(struct ipoe_serv *serv, in_addr_t addr, int mask) -{ - struct ifaddr *a; - - pthread_mutex_lock(&serv->lock); - - if (serv->opt_shared) { - list_for_each_entry(a, &serv->addr_list, entry) { - if (a->addr == addr) { - a->refs++; - pthread_mutex_unlock(&serv->lock); - - return; - } - } - } - - a = _malloc(sizeof(*a)); - a->addr = addr; - a->mask = mask; - a->refs = 1; - list_add_tail(&a->entry, &serv->addr_list); - - if (ipaddr_add(serv->ifindex, a->addr, mask)) - log_warn("ipoe: failed to add addess to interface '%s'\n", serv->ifname); - - pthread_mutex_unlock(&serv->lock); -} - -static void ipoe_serv_del_addr(struct ipoe_serv *serv, in_addr_t addr, int lock) -{ - struct ifaddr *a; - - if (lock) - pthread_mutex_lock(&serv->lock); - - list_for_each_entry(a, &serv->addr_list, entry) { - if (a->addr == addr) { - if (--a->refs == 0) { - if (ipaddr_del(serv->ifindex, a->addr, a->mask)) - log_warn("ipoe: failed to delete addess from interface '%s'\n", serv->ifname); - list_del(&a->entry); - _free(a); - } - break; - } - } - - if (lock) - pthread_mutex_unlock(&serv->lock); -} - -static void ipoe_ifcfg_add(struct ipoe_session *ses) -{ - struct ipoe_serv *serv = ses->serv; - - if (ses->serv->opt_ifcfg) - ipoe_serv_add_addr(ses->serv, ses->siaddr, conf_ip_unnumbered ? 32 : ses->mask); - - if (conf_ip_unnumbered) { - if (iproute_add(serv->ifindex, ses->serv->opt_src ? ses->serv->opt_src : ses->router, ses->yiaddr, 0, conf_proto, 32)) - log_ppp_warn("ipoe: failed to add route to interface '%s'\n", serv->ifname); - } - - ses->ifcfg = 1; -} - -static void ipoe_ifcfg_del(struct ipoe_session *ses, int lock) -{ - struct ipoe_serv *serv = ses->serv; - - if (conf_ip_unnumbered) { - if (iproute_del(serv->ifindex, ses->yiaddr, conf_proto, 32)) - log_ppp_warn("ipoe: failed to delete route from interface '%s'\n", serv->ifname); - } - - if (ses->serv->opt_ifcfg) - ipoe_serv_del_addr(ses->serv, ses->siaddr, lock); -} - static void __ipoe_session_activate(struct ipoe_session *ses) { - uint32_t addr; + uint32_t addr, gw = 0; + struct ipoe_serv *serv = ses->serv; if (ses->terminating) return; if (ses->ifindex != -1) { addr = 0; - if (!ses->ses.ipv4) { + /*if (!ses->ses.ipv4) { if (ses->serv->opt_mode == MODE_L3) { addr = 1; ses->ctrl.dont_ifcfg = 1; } - } else if (ses->ses.ipv4->peer_addr != ses->yiaddr) + } else*/ + if (ses->ses.ipv4 && ses->ses.ipv4->peer_addr != ses->yiaddr) addr = ses->ses.ipv4->peer_addr; - else if (!conf_ip_unnumbered) - ses->ctrl.dont_ifcfg = 1; - if (ses->dhcpv4_request && ses->serv->opt_mode == MODE_L3) { + /*if (ses->dhcpv4_request && ses->serv->opt_mode == MODE_L3) { in_addr_t gw; - iproute_get(ses->router, &gw); + iproute_get(ses->router, &gw, NULL); if (gw) iproute_add(0, ses->siaddr, ses->yiaddr, gw, conf_proto, 32); else iproute_add(0, ses->siaddr, ses->router, gw, conf_proto, 32); - } + }*/ - if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, addr, NULL, NULL)) { + if (serv->opt_mode == MODE_L3) + iproute_get(ses->yiaddr, &gw); + + //if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, addr, gw, gw ? 0 : ses->serv->ifindex, gw ? NULL : ses->hwaddr)) { + if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, addr, gw, serv->ifindex, ses->hwaddr)) { ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 1); return; } @@ -924,17 +841,15 @@ static void __ipoe_session_activate(struct ipoe_session *ses) } if (ses->ifindex == -1) { - if (ses->serv->opt_ifcfg || (ses->serv->opt_mode == MODE_L2)) - ipoe_ifcfg_add(ses); - - ipoe_nl_add_exclude(ses->yiaddr, 32); - - ses->ctrl.dont_ifcfg = 1; - } else if (ses->ctrl.dont_ifcfg && ses->serv->opt_mode == MODE_L2) - ipaddr_add(ses->ifindex, ses->siaddr, ses->mask); + if (serv->opt_ifcfg) + ipaddr_add(serv->ifindex, ses->router, conf_ip_unnumbered ? 32 : ses->mask); + else if (!conf_ip_unnumbered) + iproute_add(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask); - if (ses->l4_redirect) - ipoe_change_l4_redirect(ses, 0); + if (conf_ip_unnumbered) + iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32); + } else + ses->ctrl.dont_ifcfg = 0; if (ses->serv->opt_mode == MODE_L2 && ses->serv->opt_ipv6 && sock6_fd != -1) { ses->ses.ipv6 = ipdb_get_ipv6(&ses->ses); @@ -950,6 +865,9 @@ static void __ipoe_session_activate(struct ipoe_session *ses) ap_session_activate(&ses->ses); + if (ses->l4_redirect) + ipoe_change_l4_redirect(ses, 0); + if (ses->dhcpv4_request) { if (ses->ses.state == AP_STATE_ACTIVE) dhcpv4_send_reply(DHCPACK, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply); @@ -1090,12 +1008,13 @@ static void ipoe_session_free(struct ipoe_session *ses) static void ipoe_session_finished(struct ap_session *s) { struct ipoe_session *ses = container_of(s, typeof(*ses), ses); + struct ipoe_serv *serv = ses->serv; struct unit_cache *uc; log_ppp_info1("ipoe: session finished\n"); if (ses->ifindex != -1) { - if (uc_size < conf_unit_cache && ipoe_nl_modify(ses->ifindex, 0, 0, "", NULL)) { + if (uc_size < conf_unit_cache && !ipoe_nl_modify(ses->ifindex, 0, 0, 0, 0, NULL)) { uc = mempool_alloc(uc_pool); uc->ifindex = ses->ifindex; pthread_mutex_lock(&uc_lock); @@ -1104,8 +1023,14 @@ static void ipoe_session_finished(struct ap_session *s) pthread_mutex_unlock(&uc_lock); } else ipoe_nl_delete(ses->ifindex); - } else - ipoe_nl_del_exclude(ses->yiaddr); + } else if (ses->started) { + if (serv->opt_ifcfg) + ipaddr_del(serv->ifindex, ses->router, conf_ip_unnumbered ? 32 : ses->mask); + else if (conf_ip_unnumbered) + iproute_del(serv->ifindex, ses->yiaddr, conf_proto, 32); + else + iproute_del(serv->ifindex, ses->yiaddr, conf_proto, ses->mask); + } if (ses->dhcp_addr) dhcpv4_put_ip(ses->serv->dhcpv4, ses->yiaddr); @@ -1113,9 +1038,6 @@ static void ipoe_session_finished(struct ap_session *s) if (ses->relay_addr && ses->serv->dhcpv4_relay) dhcpv4_relay_send_release(ses->serv->dhcpv4_relay, ses->hwaddr, ses->xid, ses->yiaddr, ses->client_id, ses->relay_agent, ses->serv->ifname, conf_agent_remote_id); - if (ses->ifcfg) - ipoe_ifcfg_del(ses, 1); - if (ses->dhcpv4) dhcpv4_free(ses->dhcpv4); @@ -1152,9 +1074,6 @@ static void ipoe_session_terminated(struct ipoe_session *ses) if (ses->l4_redirect_set) ipoe_change_l4_redirect(ses, 1); - if (!ses->serv->opt_shared) - ses->ctrl.dont_ifcfg = 1; - ap_session_finished(&ses->ses); } @@ -1850,6 +1769,8 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc if (conf_ip_pool) ses->ses.ipv4_pool_name = _strdup(conf_ip_pool); + ses->ctrl.dont_ifcfg = 1; + triton_context_register(&ses->ctx, &ses->ses); triton_context_wakeup(&ses->ctx); @@ -2098,10 +2019,8 @@ static void ipoe_serv_release(struct ipoe_serv *serv) if (serv->dhcpv4) dhcpv4_free(serv->dhcpv4); - if (serv->dhcpv4_relay) { - ipoe_serv_del_addr(serv, serv->dhcpv4_relay->giaddr, 0); + if (serv->dhcpv4_relay) dhcpv4_relay_free(serv->dhcpv4_relay, &serv->ctx); - } if (serv->arp) arpd_stop(serv->arp); @@ -2126,8 +2045,7 @@ static void ipoe_serv_release(struct ipoe_serv *serv) if (serv->timer.tpd) triton_timer_del(&serv->timer); - if (serv->opt_up) - ipoe_nl_del_interface(serv->ifindex); + ipoe_nl_del_interface(serv->ifindex); if (serv->vid) { log_info2("ipoe: remove vlan %s\n", serv->ifname); @@ -2226,10 +2144,6 @@ static void ipoe_drop_sessions(struct ipoe_serv *serv, struct ipoe_session *skip continue; ses->terminating = 1; - if (ses->ifcfg) { - ipoe_ifcfg_del(ses, 0); - ses->ifcfg = 0; - } if (ses->ses.state == AP_STATE_ACTIVE) ap_session_ifdown(&ses->ses); @@ -2490,7 +2404,9 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int } if (opt_up) - ipoe_nl_add_interface(ifindex); + ipoe_nl_add_interface(ifindex, opt_mode); + else + ipoe_nl_add_interface(ifindex, 0); pthread_mutex_lock(&serv_lock); list_for_each_entry(serv, &serv_list, entry) { @@ -2516,17 +2432,12 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int if (serv->dhcpv4_relay && (serv->dhcpv4_relay->addr != relay_addr || serv->dhcpv4_relay->giaddr != opt_giaddr)) { - if (serv->opt_ifcfg) - ipoe_serv_del_addr(serv, serv->dhcpv4_relay->giaddr, 0); dhcpv4_relay_free(serv->dhcpv4_relay, &serv->ctx); serv->dhcpv4_relay = NULL; } - if (!serv->dhcpv4_relay && serv->opt_dhcpv4 && opt_relay) { - if (opt_ifcfg) - ipoe_serv_add_addr(serv, opt_giaddr, 32); + if (!serv->dhcpv4_relay && serv->opt_dhcpv4 && opt_relay) serv->dhcpv4_relay = dhcpv4_relay_create(opt_relay, opt_giaddr, &serv->ctx, (triton_event_func)ipoe_recv_dhcpv4_relay); - } if (serv->arp && !conf_arp) { arpd_stop(serv->arp); @@ -2589,7 +2500,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int serv->ctx.close = ipoe_serv_close; serv->ctx.before_switch = ipoe_ctx_switch; pthread_mutex_init(&serv->lock, NULL); - serv->ifname = _strdup(ifname); + strcpy(serv->ifname, ifname); serv->ifindex = ifindex; serv->opt_shared = opt_shared; serv->opt_dhcpv4 = opt_dhcpv4; @@ -2608,7 +2519,6 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int serv->vid = vid; serv->active = 1; INIT_LIST_HEAD(&serv->sessions); - INIT_LIST_HEAD(&serv->addr_list); INIT_LIST_HEAD(&serv->disc_list); INIT_LIST_HEAD(&serv->req_list); memcpy(serv->hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); @@ -2621,11 +2531,8 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int if (serv->dhcpv4) serv->dhcpv4->recv = ipoe_recv_dhcpv4; - if (opt_relay) { - if (opt_ifcfg) - ipoe_serv_add_addr(serv, opt_giaddr, 32); + if (opt_relay) serv->dhcpv4_relay = dhcpv4_relay_create(opt_relay, opt_giaddr, &serv->ctx, (triton_event_func)ipoe_recv_dhcpv4_relay); - } } if (serv->opt_arp) @@ -2741,8 +2648,6 @@ static void load_interfaces(struct conf_sect_t *sect) struct ipoe_serv *serv; struct conf_option_t *opt; - ipoe_nl_delete_interfaces(); - list_for_each_entry(serv, &serv_list, entry) serv->active = 0; @@ -2760,60 +2665,13 @@ static void load_interfaces(struct conf_sect_t *sect) list_for_each_entry(serv, &serv_list, entry) { if (!serv->active && !serv->vid) { + ipoe_nl_del_interface(serv->ifindex); ipoe_drop_sessions(serv, NULL); triton_context_call(&serv->ctx, (triton_event_func)ipoe_serv_release, serv); } } } -static void parse_local_net(const char *opt) -{ - const char *ptr; - char str[17]; - in_addr_t addr; - int mask; - char *endptr; - - ptr = strchr(opt, '/'); - if (ptr) { - memcpy(str, opt, ptr - opt); - str[ptr - opt] = 0; - addr = inet_addr(str); - if (addr == INADDR_NONE) - goto out_err; - mask = strtoul(ptr + 1, &endptr, 10); - if (mask > 32) - goto out_err; - } else { - addr = inet_addr(opt); - if (addr == INADDR_NONE) - goto out_err; - mask = 24; - } - - ipoe_nl_add_net(addr, mask); - - return; - -out_err: - log_error("ipoe: failed to parse 'local-net=%s'\n", opt); -} - -static void load_local_nets(struct conf_sect_t *sect) -{ - struct conf_option_t *opt; - - ipoe_nl_delete_nets(); - - list_for_each_entry(opt, §->items, entry) { - if (strcmp(opt->name, "local-net")) - continue; - if (!opt->val) - continue; - parse_local_net(opt->val); - } -} - static void load_gw_addr(struct conf_sect_t *sect) { struct conf_option_t *opt; @@ -3369,7 +3227,6 @@ static void load_config(void) parse_offer_delay(conf_get_opt("ipoe", "offer-delay")); load_interfaces(s); - load_local_nets(s); load_vlan_mon(s); load_gw_addr(s); } diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index 8c647b78..5561646d 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -3,6 +3,7 @@ #include <stdint.h> #include <pthread.h> +#include <linux/if.h> #include "triton.h" #include "ap_session.h" @@ -20,11 +21,10 @@ struct ipoe_serv { struct list_head entry; struct triton_context_t ctx; - char *ifname; + char ifname[IFNAMSIZ]; int ifindex; uint8_t hwaddr[ETH_ALEN]; struct list_head sessions; - struct list_head addr_list; struct dhcpv4_serv *dhcpv4; struct dhcpv4_relay *dhcpv4_relay; void *arp; @@ -88,7 +88,6 @@ struct ipoe_session { #ifdef RADIUS struct rad_plugin_t radius; #endif - int ifcfg:1; int started:1; int terminating:1; int dhcp_addr:1; @@ -120,14 +119,12 @@ struct ipoe_session *ipoe_session_alloc(void); struct ipoe_serv *ipoe_find_serv(const char *ifname); -void ipoe_nl_add_net(uint32_t addr, int mask); -void ipoe_nl_delete_nets(void); -void ipoe_nl_add_interface(int ifindex); +void ipoe_nl_add_interface(int ifindex, uint8_t mode); void ipoe_nl_del_interface(int ifindex); void ipoe_nl_delete_interfaces(void); -int ipoe_nl_create(uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr); +int ipoe_nl_create(int ifindex); void ipoe_nl_delete(int ifindex); -int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr); +int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, uint32_t gw, int link_ifindex, uint8_t *hwaddr); void ipoe_nl_get_sessions(struct list_head *list); int ipoe_nl_add_exclude(uint32_t addr, int mask); void ipoe_nl_del_exclude(uint32_t addr); diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c index fa7b0a22..cd2433e9 100644 --- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c +++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c @@ -17,6 +17,7 @@ #include "log.h" #include "genl.h" #include "libnetlink.h" +#include "iputils.h" #include "ipoe.h" #include "if_ipoe.h" @@ -29,61 +30,6 @@ static struct rtnl_handle rth; static struct triton_md_handler_t mc_hnd; static int ipoe_genl_id; -void ipoe_nl_delete_nets(void) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *ghdr; - struct { - struct nlmsghdr n; - char buf[1024]; - } req; - - if (rth.fd == -1) - return; - - nlh = &req.n; - nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - nlh->nlmsg_type = ipoe_genl_id; - - ghdr = NLMSG_DATA(&req.n); - ghdr->cmd = IPOE_CMD_DEL_NET; - - addattr32(nlh, 1024, IPOE_ATTR_ADDR, 0); - - if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) - log_error("ipoe: nl_del_net: error talking to kernel\n"); -} - -void ipoe_nl_add_net(uint32_t addr, int mask) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *ghdr; - struct { - struct nlmsghdr n; - char buf[1024]; - } req; - - if (rth.fd == -1) - return; - - nlh = &req.n; - nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - nlh->nlmsg_type = ipoe_genl_id; - - ghdr = NLMSG_DATA(&req.n); - ghdr->cmd = IPOE_CMD_ADD_NET; - - mask = mask ? ~0 << (32 - mask) : 0; - - addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr); - addattr32(nlh, 1024, IPOE_ATTR_MASK, mask); - - if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) - log_error("ipoe: nl_add_net: error talking to kernel\n"); -} - int ipoe_nl_add_exclude(uint32_t addr, int mask) { struct rtnl_handle rth; @@ -152,33 +98,7 @@ void ipoe_nl_del_exclude(uint32_t addr) rtnl_close(&rth); } -void ipoe_nl_delete_interfaces(void) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *ghdr; - struct { - struct nlmsghdr n; - char buf[1024]; - } req; - - if (rth.fd == -1) - return; - - nlh = &req.n; - nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - nlh->nlmsg_type = ipoe_genl_id; - - ghdr = NLMSG_DATA(&req.n); - ghdr->cmd = IPOE_CMD_DEL_IF; - - addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, -1); - - if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) - log_error("ipoe: nl_del_iface: error talking to kernel\n"); -} - -void ipoe_nl_add_interface(int ifindex) +void ipoe_nl_add_interface(int ifindex, uint8_t mode) { struct nlmsghdr *nlh; struct genlmsghdr *ghdr; @@ -199,6 +119,7 @@ void ipoe_nl_add_interface(int ifindex) ghdr->cmd = IPOE_CMD_ADD_IF; addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex); + addattr_l(nlh, 1024, IPOE_ATTR_MODE, &mode, 1); if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) log_error("ipoe: nl_add_iface: error talking to kernel\n"); @@ -230,7 +151,12 @@ void ipoe_nl_del_interface(int ifindex) log_error("ipoe: nl_del_iface: error talking to kernel\n"); } -int ipoe_nl_create(uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr) +void ipoe_nl_delete_interfaces(void) +{ + ipoe_nl_del_interface(-1); +} + +int ipoe_nl_create(int ifindex) { struct rtnl_handle rth; struct nlmsghdr *nlh; @@ -243,10 +169,6 @@ int ipoe_nl_create(uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_ struct nlmsghdr n; char buf[1024]; } req; - union { - uint8_t hwaddr[6]; - uint64_t u64; - } u; if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC)) { log_ppp_error("ipoe: cannot open generic netlink socket\n"); @@ -261,19 +183,7 @@ int ipoe_nl_create(uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_ ghdr = NLMSG_DATA(&req.n); ghdr->cmd = IPOE_CMD_CREATE; - if (peer_addr) - addattr32(nlh, 1024, IPOE_ATTR_PEER_ADDR, peer_addr); - - if (addr) - addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr); - - if (hwaddr) { - memcpy(u.hwaddr, hwaddr, 6); - addattr_l(nlh, 1024, IPOE_ATTR_HWADDR, &u.u64, 8); - } - - if (ifname) - addattr_l(nlh, 1024, IPOE_ATTR_IFNAME, ifname, strlen(ifname) + 1); + addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex); if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) log_ppp_error("ipoe: nl_create: error talking to kernel\n"); @@ -313,7 +223,7 @@ out: return ret; } -int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr) +int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, uint32_t gw, int link_ifindex, uint8_t *hwaddr) { struct rtnl_handle rth; struct nlmsghdr *nlh; @@ -323,10 +233,6 @@ int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *i struct nlmsghdr n; char buf[1024]; } req; - union { - uint8_t hwaddr[6]; - uint64_t u64; - } u; if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC)) { log_ppp_error("ipoe: cannot open generic netlink socket\n"); @@ -344,14 +250,11 @@ int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *i addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex); addattr32(nlh, 1024, IPOE_ATTR_PEER_ADDR, peer_addr); addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr); + addattr32(nlh, 1024, IPOE_ATTR_GW_ADDR, gw); + addattr32(nlh, 1024, IPOE_ATTR_LINK_IFINDEX, link_ifindex); - if (hwaddr) { - memcpy(u.hwaddr, hwaddr, 6); - addattr_l(nlh, 1024, IPOE_ATTR_HWADDR, &u.u64, 8); - } - - if (ifname) - addattr_l(nlh, 1024, IPOE_ATTR_IFNAME, ifname, strlen(ifname) + 1); + if (hwaddr) + addattr_l(nlh, 1024, IPOE_ATTR_HWADDR, hwaddr, 6); if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) { log_ppp_error("ipoe: nl_create: error talking to kernel\n"); @@ -631,6 +534,7 @@ static void init(void) triton_context_wakeup(&mc_ctx); ipoe_nl_del_exclude(0); + ipoe_nl_delete_interfaces(); } DEFINE_INIT(19, init); |