Skip to content

Commit

Permalink
zebra: Fix crash with certain types of tunnels
Browse files Browse the repository at this point in the history
Zebra did not have a handler for tunnels in v6 for
some reason.  Add code to handle the broadcast address
for both addition and deletion.

This appears to fix the crash.  There might still need
to be some work to make the code `work` properly for
this type of tunnel.

Fixes: #2063
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
  • Loading branch information
donaldsharp committed Apr 15, 2018
1 parent a652807 commit 60c0687
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 10 deletions.
24 changes: 20 additions & 4 deletions zebra/connected.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,8 @@ void connected_delete_ipv4(struct interface *ifp, int flags,

/* Add connected IPv6 route to the interface. */
void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
uint8_t prefixlen, const char *label)
struct in6_addr *broad, uint8_t prefixlen,
const char *label)
{
struct prefix_ipv6 *p;
struct connected *ifc;
Expand All @@ -518,6 +519,14 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
p->prefixlen = prefixlen;
ifc->address = (struct prefix *)p;

if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
p = prefix_ipv6_new();
p->family = AF_INET6;
IPV6_ADDR_COPY(&p->prefix, broad);
p->prefixlen = prefixlen;
ifc->destination = (struct prefix *)p;
}

/* Label of this address. */
if (label)
ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
Expand All @@ -536,17 +545,24 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
}

void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address,
uint8_t prefixlen)
struct in6_addr *broad, uint8_t prefixlen)
{
struct prefix p;
struct prefix p, d;
struct connected *ifc;

memset(&p, 0, sizeof(struct prefix));
p.family = AF_INET6;
memcpy(&p.u.prefix6, address, sizeof(struct in6_addr));
p.prefixlen = prefixlen;

ifc = connected_check(ifp, &p);
if (broad) {
memset(&d, 0, sizeof(struct prefix));
d.family = AF_INET6;
IPV6_ADDR_COPY(&d.u.prefix, broad);
d.prefixlen = prefixlen;
ifc = connected_check_ptp(ifp, &p, &d);
} else
ifc = connected_check_ptp(ifp, &p, NULL);

connected_delete_helper(ifc, &p);
}
Expand Down
7 changes: 4 additions & 3 deletions zebra/connected.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ extern void connected_up(struct interface *ifp, struct connected *ifc);
extern void connected_down(struct interface *ifp, struct connected *ifc);

extern void connected_add_ipv6(struct interface *ifp, int flags,
struct in6_addr *address, uint8_t prefixlen,
const char *label);
struct in6_addr *address, struct in6_addr *broad,
uint8_t prefixlen, const char *label);
extern void connected_delete_ipv6(struct interface *ifp,
struct in6_addr *address, uint8_t prefixlen);
struct in6_addr *address,
struct in6_addr *broad, uint8_t prefixlen);

extern int connected_is_unnumbered(struct interface *);

Expand Down
2 changes: 1 addition & 1 deletion zebra/if_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static int if_getaddrs(void)
}
#endif

connected_add_ipv6(ifp, flags, &addr->sin6_addr,
connected_add_ipv6(ifp, flags, &addr->sin6_addr, NULL,
prefixlen, NULL);
}
}
Expand Down
2 changes: 1 addition & 1 deletion zebra/if_ioctl_solaris.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr,
connected_add_ipv4(ifp, flags, &SIN(addr)->sin_addr, prefixlen,
(struct in_addr *)dest_pnt, label);
else if (af == AF_INET6)
connected_add_ipv6(ifp, flags, &SIN6(addr)->sin6_addr,
connected_add_ipv6(ifp, flags, &SIN6(addr)->sin6_addr, NULL,
prefixlen, label);

return 0;
Expand Down
2 changes: 2 additions & 0 deletions zebra/if_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1006,9 +1006,11 @@ int netlink_interface_addr(struct sockaddr_nl *snl, struct nlmsghdr *h,
& (IFA_F_DADFAILED | IFA_F_TENTATIVE)))
connected_add_ipv6(ifp, flags,
(struct in6_addr *)addr,
(struct in6_addr *)broad,
ifa->ifa_prefixlen, label);
} else
connected_delete_ipv6(ifp, (struct in6_addr *)addr,
(struct in6_addr *)broad,
ifa->ifa_prefixlen);
}

Expand Down
3 changes: 2 additions & 1 deletion zebra/kernel_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,10 +771,11 @@ int ifam_read(struct ifa_msghdr *ifam)

if (ifam->ifam_type == RTM_NEWADDR)
connected_add_ipv6(ifp, flags, &addr.sin6.sin6_addr,
NULL,
ip6_masklen(mask.sin6.sin6_addr),
(isalias ? ifname : NULL));
else
connected_delete_ipv6(ifp, &addr.sin6.sin6_addr,
connected_delete_ipv6(ifp, &addr.sin6.sin6_addr, NULL,
ip6_masklen(mask.sin6.sin6_addr));
break;
default:
Expand Down

0 comments on commit 60c0687

Please sign in to comment.