Skip to content
Permalink
Browse files

No commit message

  • Loading branch information...
donaldsharp committed Jun 11, 2015
1 parent 8a92a8a commit 5c610fafc4fc8d2f62d5a043e5029564f7c58824
Showing with 159 additions and 3 deletions.
  1. +62 −0 zebra/interface.c
  2. +3 −0 zebra/interface.h
  3. +5 −0 zebra/kernel_null.c
  4. +75 −3 zebra/rt_netlink.c
  5. +3 −0 zebra/rt_netlink.h
  6. +6 −0 zebra/zebra_rib.c
  7. +5 −0 zebra/zserv.c
@@ -41,6 +41,7 @@
#include "zebra/debug.h"
#include "zebra/irdp.h"
#include "zebra/zebra_ptm.h"
#include "zebra/rt_netlink.h"

#define ZEBRA_PTM_SUPPORT

@@ -528,6 +529,64 @@ if_delete_update (struct interface *ifp)
ifp->ifindex = IFINDEX_INTERNAL;
}

void
ipv6_ll_address_to_mac (struct in6_addr *address, u_char *mac)
{
mac[0] = address->s6_addr[8];
mac[0] &= ~0x02;
mac[1] = address->s6_addr[9];
mac[2] = address->s6_addr[10];
mac[3] = address->s6_addr[13];
mac[4] = address->s6_addr[14];
mac[5] = address->s6_addr[15];
}

void
if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp,
struct in6_addr *address,
int add)
{
char buf[16] = "169.254.0.1";
struct in_addr ipv4_ll;
u_char mac[6];

inet_pton (AF_INET, buf, &ipv4_ll);

ipv6_ll_address_to_mac(address, mac);
netlink_neigh_update (add ? RTM_NEWNEIGH : RTM_DELNEIGH,
ifp->ifindex, ipv4_ll.s_addr, mac, 6);
}

void
if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (struct interface *ifp)
{
if (listhead(ifp->nbr_connected))
{
struct nbr_connected *nbr_connected;
struct listnode *node;

for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
&nbr_connected->address->u.prefix6,
1);
}
}

void
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp)
{
if (listhead(ifp->nbr_connected))
{
struct nbr_connected *nbr_connected;
struct listnode *node;

for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
&nbr_connected->address->u.prefix6,
0);
}
}

/* Interface is up. */
void
if_up (struct interface *ifp)
@@ -545,6 +604,7 @@ if_up (struct interface *ifp)
}
zebra_interface_up_update (ifp);

if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);

/* Install connected routes to the kernel. */
if (ifp->connected)
@@ -597,6 +657,8 @@ if_down (struct interface *ifp)

/* Examine all static routes which direct to the interface. */
rib_update ();

if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
}

void
@@ -213,6 +213,9 @@ struct zebra_if
#endif /* SUNOS_5 */
};

extern void if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp,
struct in6_addr *address, int add);
extern void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp);
extern void if_delete_update (struct interface *ifp);
extern void if_add_update (struct interface *ifp);
extern void if_up (struct interface *);
@@ -48,6 +48,11 @@ int kernel_address_delete_ipv4 (struct interface *a, struct connected *b)
return 0;
}

int netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
{
return 0;
}

void kernel_init (void) { return; }
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
#pragma weak route_read = kernel_init
@@ -1483,8 +1483,30 @@ _netlink_route_build_singlepath(
size_t req_size,
int cmd)
{

if (rtmsg->rtm_family == AF_INET &&
(nexthop->type == NEXTHOP_TYPE_IPV6
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX))
{
char buf[16] = "169.254.0.1";
struct in_addr ipv4_ll;

inet_pton (AF_INET, buf, &ipv4_ll);
rtmsg->rtm_flags |= RTNH_F_ONLINK;
addattr_l (nlmsg, req_size, RTA_GATEWAY, &ipv4_ll, 4);
addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);

if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(" 5549: _netlink_route_build_singlepath() (%s): "
"nexthop via %s if %u",
routedesc, buf, nexthop->ifindex);
return;
}

if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
rtmsg->rtm_flags |= RTNH_F_ONLINK;

if (nexthop->type == NEXTHOP_TYPE_IPV4
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
{
@@ -1573,14 +1595,38 @@ _netlink_route_build_multipath(
struct nexthop *nexthop,
struct rtattr *rta,
struct rtnexthop *rtnh,
union g_addr **src
)
struct rtmsg *rtmsg,
union g_addr **src)
{
rtnh->rtnh_len = sizeof (*rtnh);
rtnh->rtnh_flags = 0;
rtnh->rtnh_hops = 0;
rta->rta_len += rtnh->rtnh_len;

if (rtmsg->rtm_family == AF_INET &&
(nexthop->type == NEXTHOP_TYPE_IPV6
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX))
{
char buf[16] = "169.254.0.1";
struct in_addr ipv4_ll;

inet_pton (AF_INET, buf, &ipv4_ll);
bytelen = 4;
rtnh->rtnh_flags |= RTNH_F_ONLINK;
rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
&ipv4_ll, bytelen);
rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
rtnh->rtnh_ifindex = nexthop->ifindex;

if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(" 5549: netlink_route_build_multipath() (%s): "
"nexthop via %s if %u",
routedesc, buf, nexthop->ifindex);
return;
}


if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
rtnh->rtnh_flags |= RTNH_F_ONLINK;

@@ -1683,6 +1729,32 @@ _netlink_route_debug(
}
}

int
netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
{
struct {
struct nlmsghdr n;
struct ndmsg ndm;
char buf[256];
} req;

memset(&req.n, 0, sizeof(req.n));
memset(&req.ndm, 0, sizeof(req.ndm));

req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
req.n.nlmsg_type = cmd; //RTM_NEWNEIGH or RTM_DELNEIGH
req.ndm.ndm_family = AF_INET;
req.ndm.ndm_state = NUD_PERMANENT;
req.ndm.ndm_ifindex = ifindex;
req.ndm.ndm_type = RTN_UNICAST;

addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);

return netlink_talk (&req.n, &netlink_cmd);
}

/* Routing table change via netlink interface. */
/* Update flag indicates whether this is a "replace" or not. */
static int
@@ -1874,7 +1946,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
_netlink_route_debug(cmd, p, nexthop,
routedesc, family);
_netlink_route_build_multipath(routedesc, bytelen,
nexthop, rta, rtnh, &src1);
nexthop, rta, rtnh, &req.r, &src1);
rtnh = RTNH_NEXT (rtnh);

if (cmd == RTM_NEWROUTE)
@@ -41,6 +41,9 @@ nl_msg_type_to_str (uint16_t msg_type);
extern const char *
nl_rtproto_to_str (u_char rtproto);

int
netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen);

extern int netlink_route_read(void);
extern int interface_lookup_netlink(void);

@@ -3962,8 +3962,14 @@ rib_close_table (struct route_table *table)
void
rib_close (void)
{
struct listnode *node, *nnode;
struct interface *ifp;

rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));

for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
}

/* Routing information base initialize. */
@@ -44,6 +44,7 @@
#include "zebra/debug.h"
#include "zebra/ipforward.h"
#include "zebra/zebra_rnh.h"
#include "zebra/rt_netlink.h"

/* Event list of zebra. */
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
@@ -415,6 +416,8 @@ nbr_connected_replacement_add_ipv6 (struct interface *ifp, struct in6_addr *addr
prefix_copy(ifc->address, &p);

zebra_interface_nbr_address_add_update (ifp, ifc);

if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1);
}

void
@@ -436,6 +439,8 @@ nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,

zebra_interface_nbr_address_delete_update (ifp, ifc);

if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0);

nbr_connected_free (ifc);
}

0 comments on commit 5c610fa

Please sign in to comment.
You can’t perform that action at this time.