diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index f864d2f63825fe4cce2dbaa545749da3253c7912..d38e73d1a65b9f896fc7105bd76cda5e33b1d177 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -156,6 +156,7 @@ static int conf_proto; static LIST_HEAD(conf_offer_delay); static const char *conf_vlan_name; static int conf_ip_unnumbered; +static int conf_ip_unnumbered_peer_mode; static int conf_check_mac_change; static int conf_soft_terminate; static int conf_calling_sid = SID_MAC; @@ -888,11 +889,15 @@ static void __ipoe_session_activate(struct ipoe_session *ses) if (ses->ifindex == -1) { if (serv->opt_ifcfg) - ipaddr_add(serv->ifindex, ses->router, conf_ip_unnumbered ? 32 : ses->mask); + if(conf_ip_unnumbered && conf_ip_unnumbered_peer_mode) { + ipaddr_add_peer(serv->ifindex, ses->router, 32, ses->yiaddr); + } else { + 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 (conf_ip_unnumbered) + if (conf_ip_unnumbered && !conf_ip_unnumbered_peer_mode) iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32); } else ses->ctrl.dont_ifcfg = 0; @@ -3478,6 +3483,12 @@ static void load_config(void) else conf_ip_unnumbered = 1; + opt = conf_get_opt("ipoe", "ip-unnumbered-peer-mode"); + if (opt) + conf_ip_unnumbered_peer_mode = atoi(opt); + else + conf_ip_unnumbered_peer_mode = 0; + opt = conf_get_opt("ipoe", "idle-timeout"); if (opt) conf_idle_timeout = atoi(opt); diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c index 7a29d08f4531d7b81fce7605d23e53a19d3ba439..8bcee50d99329089ec47d80d98e26338a8a5b1d3 100644 --- a/accel-pppd/libnetlink/iputils.c +++ b/accel-pppd/libnetlink/iputils.c @@ -329,6 +329,39 @@ int __export ipaddr_add(int ifindex, in_addr_t addr, int mask) return r; } +int __export ipaddr_add_peer(int ifindex, in_addr_t addr, int mask, in_addr_t peer_addr) +{ + struct ipaddr_req { + struct nlmsghdr n; + struct ifaddrmsg i; + char buf[4096]; + } req; + struct rtnl_handle *rth = net->rtnl_get(); + int r = 0; + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 4096); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; + req.n.nlmsg_type = RTM_NEWADDR; + req.i.ifa_family = AF_INET; + req.i.ifa_index = ifindex; + req.i.ifa_prefixlen = mask; + + addattr32(&req.n, sizeof(req), IFA_LOCAL, addr); + addattr32(&req.n, sizeof(req), IFA_ADDRESS, peer_addr); + + if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) + r = -1; + + net->rtnl_put(rth); + + return r; +} + int __export ipaddr_del(int ifindex, in_addr_t addr, int mask) { struct ipaddr_req { diff --git a/accel-pppd/libnetlink/iputils.h b/accel-pppd/libnetlink/iputils.h index dad068700c72e31cc63f2b1d9e106a53ac98fca7..a623197fe3361c6c662cc425ae0920f8ff37f8a9 100644 --- a/accel-pppd/libnetlink/iputils.h +++ b/accel-pppd/libnetlink/iputils.h @@ -13,6 +13,7 @@ int iplink_vlan_del(int ifindex); int iplink_vlan_get_vid(int ifindex, int *iflink); int ipaddr_add(int ifindex, in_addr_t addr, int mask); +int ipaddr_add_peer(int ifindex, in_addr_t addr, int mask, in_addr_t peer_addr); int ipaddr_del(int ifindex, in_addr_t addr, int mask); int iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask);