@@ -38,7 +38,7 @@ extern struct zclient *zclient;
38
38
39
39
static void register_zebra_rnh (struct bgp_nexthop_cache * bnc );
40
40
static void unregister_zebra_rnh (struct bgp_nexthop_cache * bnc );
41
- static int make_prefix (int afi , struct bgp_path_info * pi , struct prefix * p );
41
+ static bool make_prefix (int afi , struct bgp_path_info * pi , struct prefix * p );
42
42
static void bgp_nht_ifp_initial (struct event * thread );
43
43
44
44
DEFINE_HOOK (bgp_nht_path_update , (struct bgp * bgp , struct bgp_path_info * pi , bool valid ),
@@ -330,7 +330,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
330
330
331
331
/* This will return true if the global IPv6 NH is a link local
332
332
* addr */
333
- if (make_prefix (afi , pi , & p ) < 0 )
333
+ if (! make_prefix (afi , pi , & p ))
334
334
return 1 ;
335
335
336
336
/*
@@ -1026,7 +1026,7 @@ void bgp_cleanup_nexthops(struct bgp *bgp)
1026
1026
* make_prefix - make a prefix structure from the path (essentially
1027
1027
* path's node.
1028
1028
*/
1029
- static int make_prefix (int afi , struct bgp_path_info * pi , struct prefix * p )
1029
+ static bool make_prefix (int afi , struct bgp_path_info * pi , struct prefix * p )
1030
1030
{
1031
1031
1032
1032
int is_bgp_static = ((pi -> type == ZEBRA_ROUTE_BGP )
@@ -1036,12 +1036,13 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
1036
1036
struct bgp_dest * net = pi -> net ;
1037
1037
const struct prefix * p_orig = bgp_dest_get_prefix (net );
1038
1038
struct in_addr ipv4 ;
1039
+ struct peer * peer = pi -> peer ;
1040
+ struct attr * attr = pi -> attr ;
1039
1041
1040
1042
if (p_orig -> family == AF_FLOWSPEC ) {
1041
- if (!pi -> peer )
1042
- return -1 ;
1043
- return bgp_flowspec_get_first_nh (pi -> peer -> bgp ,
1044
- pi , p , afi );
1043
+ if (!peer )
1044
+ return false;
1045
+ return bgp_flowspec_get_first_nh (peer -> bgp , pi , p , afi );
1045
1046
}
1046
1047
memset (p , 0 , sizeof (struct prefix ));
1047
1048
switch (afi ) {
@@ -1051,63 +1052,68 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
1051
1052
p -> u .prefix4 = p_orig -> u .prefix4 ;
1052
1053
p -> prefixlen = p_orig -> prefixlen ;
1053
1054
} else {
1054
- if (IS_MAPPED_IPV6 (& pi -> attr -> mp_nexthop_global )) {
1055
- ipv4_mapped_ipv6_to_ipv4 (
1056
- & pi -> attr -> mp_nexthop_global , & ipv4 );
1055
+ if (IS_MAPPED_IPV6 (& attr -> mp_nexthop_global )) {
1056
+ ipv4_mapped_ipv6_to_ipv4 (& attr -> mp_nexthop_global , & ipv4 );
1057
1057
p -> u .prefix4 = ipv4 ;
1058
1058
p -> prefixlen = IPV4_MAX_BITLEN ;
1059
1059
} else {
1060
1060
if (p_orig -> family == AF_EVPN )
1061
- p -> u .prefix4 =
1062
- pi -> attr -> mp_nexthop_global_in ;
1061
+ p -> u .prefix4 = attr -> mp_nexthop_global_in ;
1063
1062
else
1064
- p -> u .prefix4 = pi -> attr -> nexthop ;
1063
+ p -> u .prefix4 = attr -> nexthop ;
1065
1064
p -> prefixlen = IPV4_MAX_BITLEN ;
1066
1065
}
1067
1066
}
1068
1067
break ;
1069
1068
case AFI_IP6 :
1070
1069
p -> family = AF_INET6 ;
1071
- if (pi -> attr -> srv6_l3vpn ) {
1070
+ if (attr -> srv6_l3vpn ) {
1072
1071
p -> prefixlen = IPV6_MAX_BITLEN ;
1073
- if (pi -> attr -> srv6_l3vpn -> transposition_len != 0 &&
1072
+ if (attr -> srv6_l3vpn -> transposition_len != 0 &&
1074
1073
BGP_PATH_INFO_NUM_LABELS (pi )) {
1075
- IPV6_ADDR_COPY (& p -> u .prefix6 , & pi -> attr -> srv6_l3vpn -> sid );
1074
+ IPV6_ADDR_COPY (& p -> u .prefix6 , & attr -> srv6_l3vpn -> sid );
1076
1075
transpose_sid (& p -> u .prefix6 ,
1077
1076
decode_label (& pi -> extra -> labels -> label [0 ]),
1078
- pi -> attr -> srv6_l3vpn -> transposition_offset ,
1079
- pi -> attr -> srv6_l3vpn -> transposition_len );
1077
+ attr -> srv6_l3vpn -> transposition_offset ,
1078
+ attr -> srv6_l3vpn -> transposition_len );
1080
1079
} else
1081
- IPV6_ADDR_COPY (& (p -> u .prefix6 ), & (pi -> attr -> srv6_l3vpn -> sid ));
1080
+ IPV6_ADDR_COPY (& (p -> u .prefix6 ), & (attr -> srv6_l3vpn -> sid ));
1082
1081
} else if (is_bgp_static ) {
1083
1082
p -> u .prefix6 = p_orig -> u .prefix6 ;
1084
1083
p -> prefixlen = p_orig -> prefixlen ;
1085
1084
} else {
1086
1085
/* If we receive MP_REACH nexthop with ::(LL)
1087
1086
* or LL(LL), use LL address as nexthop cache.
1088
1087
*/
1089
- if (pi -> attr &&
1090
- pi -> attr -> mp_nexthop_len ==
1091
- BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL &&
1092
- (IN6_IS_ADDR_UNSPECIFIED (
1093
- & pi -> attr -> mp_nexthop_global ) ||
1094
- IN6_IS_ADDR_LINKLOCAL (& pi -> attr -> mp_nexthop_global )))
1095
- p -> u .prefix6 = pi -> attr -> mp_nexthop_local ;
1088
+ if (attr && attr -> mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL &&
1089
+ (IN6_IS_ADDR_UNSPECIFIED (& attr -> mp_nexthop_global ) ||
1090
+ IN6_IS_ADDR_LINKLOCAL (& attr -> mp_nexthop_global )))
1091
+ p -> u .prefix6 = attr -> mp_nexthop_local ;
1096
1092
/* If we receive MR_REACH with (GA)::(LL)
1097
1093
* then check for route-map to choose GA or LL
1098
1094
*/
1099
- else if (pi -> attr &&
1100
- pi -> attr -> mp_nexthop_len ==
1101
- BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL ) {
1102
- if (CHECK_FLAG (pi -> attr -> nh_flags ,
1103
- BGP_ATTR_NH_MP_PREFER_GLOBAL ))
1104
- p -> u .prefix6 =
1105
- pi -> attr -> mp_nexthop_global ;
1095
+ else if (attr && attr -> mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL ) {
1096
+ if (CHECK_FLAG (attr -> nh_flags , BGP_ATTR_NH_MP_PREFER_GLOBAL ))
1097
+ p -> u .prefix6 = attr -> mp_nexthop_global ;
1106
1098
else
1107
- p -> u .prefix6 =
1108
- pi -> attr -> mp_nexthop_local ;
1099
+ p -> u .prefix6 = attr -> mp_nexthop_local ;
1100
+ } else if (attr && attr -> mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL &&
1101
+ IN6_IS_ADDR_LINKLOCAL (& attr -> mp_nexthop_global )) {
1102
+ /* If we receive MP_REACH with GUA as LL, we should
1103
+ * check if we have Link-Local Next Hop capability also.
1104
+ */
1105
+ if (!(CHECK_FLAG (peer -> cap , PEER_CAP_LINK_LOCAL_ADV ) &&
1106
+ CHECK_FLAG (peer -> cap , PEER_CAP_LINK_LOCAL_RCV ))) {
1107
+ zlog_warn ("%s: received IPv6 global next-hop as Link-Local, but no capability exchanged" ,
1108
+ __func__ );
1109
+ p -> u .prefix6 = attr -> mp_nexthop_global ;
1110
+ } else {
1111
+ p -> u .prefix6 = attr -> mp_nexthop_global ;
1112
+ p -> prefixlen = IPV6_MAX_BITLEN ;
1113
+ return false;
1114
+ }
1109
1115
} else
1110
- p -> u .prefix6 = pi -> attr -> mp_nexthop_global ;
1116
+ p -> u .prefix6 = attr -> mp_nexthop_global ;
1111
1117
p -> prefixlen = IPV6_MAX_BITLEN ;
1112
1118
}
1113
1119
break ;
@@ -1119,7 +1125,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
1119
1125
}
1120
1126
break ;
1121
1127
}
1122
- return 0 ;
1128
+ return true ;
1123
1129
}
1124
1130
1125
1131
/**
0 commit comments