summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/ipoe
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2016-03-13 00:20:49 +0300
committerDmitry Kozlov <xeb@mail.ru>2016-03-13 11:33:14 +0300
commitc45b00d84de954d7f27fc7dce2909fab198cc298 (patch)
treea1cb5306b63a5e43282ce6c193d6529c3a6c1e62 /accel-pppd/ctrl/ipoe
parentd01f9f7161eb5d46a656fd1cff1baf41a65d769f (diff)
downloadaccel-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.c241
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h13
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe_netlink.c128
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, &sect->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);