Skip to content

Commit

Permalink
Merge pull request #2590 from opensourcerouting/tunnel_fixes
Browse files Browse the repository at this point in the history
[4.0] Cherry-pick two commits to fix crash with p2p interfaces on *BSD
  • Loading branch information
donaldsharp authored Jul 2, 2018
2 parents 17a362c + b1c008d commit c19bc04
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 14 deletions.
30 changes: 26 additions & 4 deletions zebra/connected.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,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,
u_char prefixlen, const char *label)
struct in6_addr *broad, uint8_t prefixlen,
const char *label)
{
struct prefix_ipv6 *p;
struct connected *ifc;
Expand All @@ -509,6 +510,20 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
p->prefixlen = prefixlen;
ifc->address = (struct prefix *)p;

if (broad) {
p = prefix_ipv6_new();
p->family = AF_INET6;
IPV6_ADDR_COPY(&p->prefix, broad);
p->prefixlen = prefixlen;
ifc->destination = (struct prefix *)p;
} else {
if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
zlog_warn("warning: %s called for interface %s with peer flag set, but no peer address supplied",
__func__, ifp->name);
UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
}
}

/* Label of this address. */
if (label)
ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
Expand All @@ -527,17 +542,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,
u_char 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, u_char 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, u_char 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 @@ -985,9 +985,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
11 changes: 7 additions & 4 deletions zebra/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,10 +395,13 @@ void if_get_flags(struct interface *ifp)
strncpy(ifmr.ifm_name, ifp->name, IFNAMSIZ);

/* Seems not all interfaces implement this ioctl */
if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s",
safe_strerror(errno));
else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
/* Ignore EINVAL to avoid being too verbose */
if (errno != EINVAL)
zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s",
safe_strerror(errno));
} else if (ifmr.ifm_status
& IFM_AVALID) /* Link state is valid */
{
if (ifmr.ifm_status & IFM_ACTIVE)
SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
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 c19bc04

Please sign in to comment.