Skip to content

Commit

Permalink
Fix for nexthop as IPv4 mapped IPv6 address
Browse files Browse the repository at this point in the history
BUG No. #6341 and #6382
lib : Added a macro to validate the IPv4 Mapped IPv6 address.
bgp : Modifications done for bgp receive and while sending updates
for IPv4 Mapped IPv6 address.
zebra : Modifications done for installing IPv4 Mapped IPv6 address as nexthop
in RIB. Minor correction done in fpm while sending the routes for
nexthop as IPv4 Mapped IPv6 address.

Signed-off-by: Kaushik <kaushik@niralnetworks.com>
  • Loading branch information
KaushikNiral committed May 25, 2020
1 parent ed741b6 commit ab51820
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 22 deletions.
10 changes: 6 additions & 4 deletions bgpd/bgp_nht.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
afi = BGP_ATTR_NEXTHOP_AFI_IP6(pi->attr) ? AFI_IP6
: AFI_IP;
/* Validation for the ipv4 mapped ipv6 nexthop. */
if(VALIDATE_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) {
if (VALIDATE_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) {
afi = AFI_IP;
}

Expand Down Expand Up @@ -536,7 +536,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
: 0;
struct bgp_node *net = pi->net;
const struct prefix *p_orig = bgp_node_get_prefix(net);
struct in_addr ipv4;
struct in_addr ipv4;

if (p_orig->family == AF_FLOWSPEC) {
if (!pi->peer)
Expand All @@ -552,8 +552,10 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
p->u.prefix4 = p_orig->u.prefix4;
p->prefixlen = p_orig->prefixlen;
} else {
if (VALIDATE_MAPPED_IPV6 (&pi->attr->mp_nexthop_global)) {
ipv4_mapped_ipv6_to_ipv4(&pi->attr->mp_nexthop_global, &ipv4);
if (VALIDATE_MAPPED_IPV6(
&pi->attr->mp_nexthop_global)) {
ipv4_mapped_ipv6_to_ipv4(
&pi->attr->mp_nexthop_global, &ipv4);
p->u.prefix4 = ipv4;
p->prefixlen = IPV4_MAX_BITLEN;
} else {
Expand Down
12 changes: 8 additions & 4 deletions bgpd/bgp_updgrp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,16 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
}

if (IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg)) {
if(peer->nexthop.v4.s_addr) {
ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, peer->nexthop.v4);
if (peer->nexthop.v4.s_addr) {
ipv4_to_ipv4_mapped_ipv6(mod_v6nhg,
peer->nexthop.v4);
}
} else {
if(peer->nexthop.v4.s_addr && (!IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local))) {
ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, peer->nexthop.v4);
if (peer->nexthop.v4.s_addr
&& (!IN6_IS_ADDR_LINKLOCAL(
&peer->nexthop.v6_local))) {
ipv4_to_ipv4_mapped_ipv6(mod_v6nhg,
peer->nexthop.v4);
gnh_modified = 1;
}
}
Expand Down
10 changes: 6 additions & 4 deletions lib/ipaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,12 @@ static inline char *ipaddr2str(const struct ipaddr *ip, char *buf, int size)
return buf;
}

#define VALIDATE_MAPPED_IPV6(A) \
((A)->s6_addr32[0] == 0x00000000 ? \
((A)->s6_addr32[1] == 0x00000000 ? \
(ntohl((A)->s6_addr32[2]) == 0xFFFF ? 1 : 0): 0): 0)
#define VALIDATE_MAPPED_IPV6(A) \
((A)->s6_addr32[0] == 0x00000000 \
? ((A)->s6_addr32[1] == 0x00000000 \
? (ntohl((A)->s6_addr32[2]) == 0xFFFF ? 1 : 0) \
: 0) \
: 0)

/*
* Convert IPv4 address to IPv4-mapped IPv6 address which is of the
Expand Down
7 changes: 4 additions & 3 deletions zebra/rt_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,14 +1047,15 @@ static void _netlink_route_nl_add_gateway_info(uint8_t route_family,
bytelen + 2);
} else {

if(nexthop->rparent && VALIDATE_MAPPED_IPV6(&nexthop->rparent->gate.ipv6)) {
if (nexthop->rparent
&& VALIDATE_MAPPED_IPV6(&nexthop->rparent->gate.ipv6)) {
} else {
if (gw_family == AF_INET)
addattr_l(nlmsg, req_size, RTA_GATEWAY,
&nexthop->gate.ipv4, bytelen);
&nexthop->gate.ipv4, bytelen);
else
addattr_l(nlmsg, req_size, RTA_GATEWAY,
&nexthop->gate.ipv6, bytelen);
&nexthop->gate.ipv6, bytelen);
}
}
}
Expand Down
12 changes: 7 additions & 5 deletions zebra/zebra_fpm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,13 +422,15 @@ static int netlink_route_info_encode(struct netlink_route_info *ri,
if (ri->num_nhs == 1) {
nhi = &ri->nhs[0];
if (nhi->gateway) {
if(nhi->type == NEXTHOP_TYPE_IPV4_IFINDEX && ri->af == AF_INET6) {
ipv4_to_ipv4_mapped_ipv6(&ipv6, nhi->gateway->ipv4);
if (nhi->type == NEXTHOP_TYPE_IPV4_IFINDEX
&& ri->af == AF_INET6) {
ipv4_to_ipv4_mapped_ipv6(&ipv6,
nhi->gateway->ipv4);
addattr_l(&req->n, in_buf_len, RTA_GATEWAY,
&ipv6, bytelen);
&ipv6, bytelen);
} else
addattr_l(&req->n, in_buf_len, RTA_GATEWAY,
nhi->gateway, bytelen);
addattr_l(&req->n, in_buf_len, RTA_GATEWAY,
nhi->gateway, bytelen);
}

if (nhi->if_index) {
Expand Down
4 changes: 2 additions & 2 deletions zebra/zebra_nhg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1829,7 +1829,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
}

/* Validation for ipv4 mapped ipv6 nexthop. */
if (VALIDATE_MAPPED_IPV6 (&nexthop->gate.ipv6)) {
if (VALIDATE_MAPPED_IPV6(&nexthop->gate.ipv6)) {
afi = AFI_IP;
}
/* Make lookup prefix. */
Expand All @@ -1838,7 +1838,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
case AFI_IP:
p.family = AF_INET;
p.prefixlen = IPV4_MAX_PREFIXLEN;
if (VALIDATE_MAPPED_IPV6 (&nexthop->gate.ipv6)) {
if (VALIDATE_MAPPED_IPV6(&nexthop->gate.ipv6)) {
ipv4_mapped_ipv6_to_ipv4(&nexthop->gate.ipv6, &ipv4);
p.u.prefix4 = ipv4;
} else {
Expand Down

0 comments on commit ab51820

Please sign in to comment.