Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.0] Cherry-pick two commits to fix crash with p2p interfaces on *BSD #2590

Merged
merged 3 commits into from
Jul 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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