mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 07:23:41 +00:00
bgpd: support for redirect ipv6 simpson method
this commit supports [0] where ipv6 address is encoded in nexthop attribute of nlri, and not in bgp redirect ip extended community. the community contains only duplicate information or not. Adding to this, because an action or a rule needs to apply to either ipv4 or ipv6 flow, modify some internal structures so as to be aware of which flow needs to be filtered. This work is needed when an ipv6 flowspec rule without ip addresses is mentioned, we need to know which afi is served. Also, this work will be useful when doing redirect VRF. [0] draft-simpson-idr-flowspec-redirect-02.txt Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
4088180002
commit
f01e580fc0
@ -1052,7 +1052,8 @@ bool ecommunity_del_val(struct ecommunity *ecom, struct ecommunity_val *eval)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
|
int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
|
||||||
struct bgp_pbr_entry_action *api)
|
struct bgp_pbr_entry_action *api,
|
||||||
|
afi_t afi)
|
||||||
{
|
{
|
||||||
if (ecom_eval->val[1] == ECOMMUNITY_TRAFFIC_RATE) {
|
if (ecom_eval->val[1] == ECOMMUNITY_TRAFFIC_RATE) {
|
||||||
api->action = ACTION_TRAFFICRATE;
|
api->action = ACTION_TRAFFICRATE;
|
||||||
@ -1076,7 +1077,8 @@ int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
|
|||||||
} else if (ecom_eval->val[1] == ECOMMUNITY_REDIRECT_VRF) {
|
} else if (ecom_eval->val[1] == ECOMMUNITY_REDIRECT_VRF) {
|
||||||
/* must use external function */
|
/* must use external function */
|
||||||
return 0;
|
return 0;
|
||||||
} else if (ecom_eval->val[1] == ECOMMUNITY_REDIRECT_IP_NH) {
|
} else if (ecom_eval->val[1] == ECOMMUNITY_REDIRECT_IP_NH &&
|
||||||
|
afi == AFI_IP) {
|
||||||
/* see draft-ietf-idr-flowspec-redirect-ip-02
|
/* see draft-ietf-idr-flowspec-redirect-ip-02
|
||||||
* Q1: how come a ext. community can host ipv6 address
|
* Q1: how come a ext. community can host ipv6 address
|
||||||
* Q2 : from cisco documentation:
|
* Q2 : from cisco documentation:
|
||||||
|
@ -222,7 +222,8 @@ extern bool ecommunity_del_val(struct ecommunity *ecom,
|
|||||||
struct ecommunity_val *eval);
|
struct ecommunity_val *eval);
|
||||||
struct bgp_pbr_entry_action;
|
struct bgp_pbr_entry_action;
|
||||||
extern int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
|
extern int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
|
||||||
struct bgp_pbr_entry_action *api);
|
struct bgp_pbr_entry_action *api,
|
||||||
|
afi_t afi);
|
||||||
|
|
||||||
extern void bgp_compute_aggregate_ecommunity(
|
extern void bgp_compute_aggregate_ecommunity(
|
||||||
struct bgp_aggregate *aggregate,
|
struct bgp_aggregate *aggregate,
|
||||||
|
@ -325,10 +325,28 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,
|
|||||||
json_object_array_add(json_paths,
|
json_object_array_add(json_paths,
|
||||||
json_ecom_path);
|
json_ecom_path);
|
||||||
}
|
}
|
||||||
if (attr->nexthop.s_addr != 0 &&
|
if (display == NLRI_STRING_FORMAT_LARGE) {
|
||||||
display == NLRI_STRING_FORMAT_LARGE)
|
char local_buff[INET6_ADDRSTRLEN];
|
||||||
vty_out(vty, "\tNLRI NH %-16s\n",
|
|
||||||
inet_ntoa(attr->nexthop));
|
local_buff[0] = '\0';
|
||||||
|
if (p->u.prefix_flowspec.family == AF_INET &&
|
||||||
|
attr->nexthop.s_addr != 0)
|
||||||
|
inet_ntop(AF_INET,
|
||||||
|
&attr->nexthop.s_addr,
|
||||||
|
local_buff,
|
||||||
|
INET6_ADDRSTRLEN);
|
||||||
|
else if (p->u.prefix_flowspec.family == AF_INET6 &&
|
||||||
|
attr->mp_nexthop_len != 0 &&
|
||||||
|
attr->mp_nexthop_len != BGP_ATTR_NHLEN_IPV4 &&
|
||||||
|
attr->mp_nexthop_len != BGP_ATTR_NHLEN_VPNV4)
|
||||||
|
inet_ntop(AF_INET6,
|
||||||
|
&attr->mp_nexthop_global,
|
||||||
|
local_buff,
|
||||||
|
INET6_ADDRSTRLEN);
|
||||||
|
if (local_buff[0] != '\0')
|
||||||
|
vty_out(vty, "\tNLRI NH %s\n",
|
||||||
|
local_buff);
|
||||||
|
}
|
||||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||||
}
|
}
|
||||||
peer_uptime(path->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL);
|
peer_uptime(path->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL);
|
||||||
|
@ -248,6 +248,7 @@ struct bgp_pbr_val_mask {
|
|||||||
struct bgp_pbr_filter {
|
struct bgp_pbr_filter {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
vrf_id_t vrf_id;
|
vrf_id_t vrf_id;
|
||||||
|
uint8_t family;
|
||||||
struct prefix *src;
|
struct prefix *src;
|
||||||
struct prefix *dst;
|
struct prefix *dst;
|
||||||
uint8_t bitmask_iprule;
|
uint8_t bitmask_iprule;
|
||||||
@ -793,9 +794,10 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p,
|
|||||||
* do not overwrite
|
* do not overwrite
|
||||||
* draft-ietf-idr-flowspec-redirect
|
* draft-ietf-idr-flowspec-redirect
|
||||||
*/
|
*/
|
||||||
if (api_action_redirect_ip) {
|
if (api_action_redirect_ip &&
|
||||||
if (api_action_redirect_ip->u.zr
|
p->u.prefix_flowspec.family == AF_INET) {
|
||||||
.redirect_ip_v4.s_addr
|
if (api_action_redirect_ip->u
|
||||||
|
.zr.redirect_ip_v4.s_addr
|
||||||
!= INADDR_ANY)
|
!= INADDR_ANY)
|
||||||
continue;
|
continue;
|
||||||
if (path->attr->nexthop.s_addr
|
if (path->attr->nexthop.s_addr
|
||||||
@ -807,13 +809,42 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p,
|
|||||||
api_action_redirect_ip->u.zr.duplicate
|
api_action_redirect_ip->u.zr.duplicate
|
||||||
= ecom_eval->val[7];
|
= ecom_eval->val[7];
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else if (api_action_redirect_ip &&
|
||||||
|
p->u.prefix_flowspec.family == AF_INET6) {
|
||||||
|
if (memcmp(&api_action_redirect_ip->u
|
||||||
|
.zr.redirect_ip_v6,
|
||||||
|
&in6addr_any,
|
||||||
|
sizeof(struct in6_addr)))
|
||||||
|
continue;
|
||||||
|
if (path->attr->mp_nexthop_len == 0 ||
|
||||||
|
path->attr->mp_nexthop_len ==
|
||||||
|
BGP_ATTR_NHLEN_IPV4 ||
|
||||||
|
path->attr->mp_nexthop_len ==
|
||||||
|
BGP_ATTR_NHLEN_VPNV4)
|
||||||
|
continue;
|
||||||
|
memcpy(&api_action_redirect_ip->u
|
||||||
|
.zr.redirect_ip_v6,
|
||||||
|
&path->attr->mp_nexthop_global,
|
||||||
|
sizeof(struct in6_addr));
|
||||||
|
api_action_redirect_ip->u.zr.duplicate
|
||||||
|
= ecom_eval->val[7];
|
||||||
|
continue;
|
||||||
|
} else if (p->u.prefix_flowspec.family == AF_INET) {
|
||||||
api_action->action = ACTION_REDIRECT_IP;
|
api_action->action = ACTION_REDIRECT_IP;
|
||||||
api_action->u.zr.redirect_ip_v4.s_addr =
|
api_action->u.zr.redirect_ip_v4.s_addr =
|
||||||
path->attr->nexthop.s_addr;
|
path->attr->nexthop.s_addr;
|
||||||
api_action->u.zr.duplicate =
|
api_action->u.zr.duplicate =
|
||||||
ecom_eval->val[7];
|
ecom_eval->val[7];
|
||||||
api_action_redirect_ip = api_action;
|
api_action_redirect_ip = api_action;
|
||||||
|
} else if (p->u.prefix_flowspec.family == AF_INET6) {
|
||||||
|
api_action->action = ACTION_REDIRECT_IP;
|
||||||
|
memcpy(&api_action->u
|
||||||
|
.zr.redirect_ip_v6,
|
||||||
|
&path->attr->mp_nexthop_global,
|
||||||
|
sizeof(struct in6_addr));
|
||||||
|
api_action->u.zr.duplicate
|
||||||
|
= ecom_eval->val[7];
|
||||||
|
api_action_redirect_ip = api_action;
|
||||||
}
|
}
|
||||||
} else if ((ecom_eval->val[0] ==
|
} else if ((ecom_eval->val[0] ==
|
||||||
(char)ECOMMUNITY_ENCODE_IP) &&
|
(char)ECOMMUNITY_ENCODE_IP) &&
|
||||||
@ -845,7 +876,8 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p,
|
|||||||
(char)ECOMMUNITY_ENCODE_TRANS_EXP)
|
(char)ECOMMUNITY_ENCODE_TRANS_EXP)
|
||||||
continue;
|
continue;
|
||||||
ret = ecommunity_fill_pbr_action(ecom_eval,
|
ret = ecommunity_fill_pbr_action(ecom_eval,
|
||||||
api_action);
|
api_action,
|
||||||
|
afi);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
continue;
|
continue;
|
||||||
if ((api_action->action == ACTION_TRAFFICRATE) &&
|
if ((api_action->action == ACTION_TRAFFICRATE) &&
|
||||||
@ -1181,6 +1213,7 @@ uint32_t bgp_pbr_action_hash_key(const void *arg)
|
|||||||
pbra = arg;
|
pbra = arg;
|
||||||
key = jhash_1word(pbra->table_id, 0x4312abde);
|
key = jhash_1word(pbra->table_id, 0x4312abde);
|
||||||
key = jhash_1word(pbra->fwmark, key);
|
key = jhash_1word(pbra->fwmark, key);
|
||||||
|
key = jhash_1word(pbra->afi, key);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1198,6 +1231,9 @@ bool bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
|
|||||||
if (r1->vrf_id != r2->vrf_id)
|
if (r1->vrf_id != r2->vrf_id)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (r1->afi != r2->afi)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (memcmp(&r1->nh, &r2->nh, sizeof(struct nexthop)))
|
if (memcmp(&r1->nh, &r2->nh, sizeof(struct nexthop)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1515,18 +1551,25 @@ void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api)
|
|||||||
ptr += delta;
|
ptr += delta;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_REDIRECT_IP:
|
case ACTION_REDIRECT_IP: {
|
||||||
char local_buff[INET_ADDRSTRLEN];
|
char local_buff[INET6_ADDRSTRLEN];
|
||||||
|
void *ptr_ip;
|
||||||
|
|
||||||
INCREMENT_DISPLAY(ptr, nb_items, len);
|
INCREMENT_DISPLAY(ptr, nb_items, len);
|
||||||
if (inet_ntop(AF_INET,
|
if (api->afi == AF_INET)
|
||||||
&api->actions[i].u.zr.redirect_ip_v4,
|
ptr_ip = &api->actions[i].u.zr.redirect_ip_v4;
|
||||||
local_buff, INET_ADDRSTRLEN) != NULL)
|
else
|
||||||
|
ptr_ip = &api->actions[i].u.zr.redirect_ip_v6;
|
||||||
|
if (inet_ntop(afi2family(api->afi),
|
||||||
|
ptr_ip, local_buff,
|
||||||
|
INET6_ADDRSTRLEN) != NULL) {
|
||||||
delta = snprintf(ptr, len,
|
delta = snprintf(ptr, len,
|
||||||
"@redirect ip nh %s", local_buff);
|
"@redirect ip nh %s", local_buff);
|
||||||
len -= delta;
|
len -= delta;
|
||||||
ptr += delta;
|
ptr += delta;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ACTION_REDIRECT: {
|
case ACTION_REDIRECT: {
|
||||||
struct vrf *vrf;
|
struct vrf *vrf;
|
||||||
|
|
||||||
@ -1639,7 +1682,7 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
|
|||||||
if (bpa->installed && bpa->table_id != 0) {
|
if (bpa->installed && bpa->table_id != 0) {
|
||||||
bgp_send_pbr_rule_action(bpa, NULL, false);
|
bgp_send_pbr_rule_action(bpa, NULL, false);
|
||||||
bgp_zebra_announce_default(bpa->bgp, &(bpa->nh),
|
bgp_zebra_announce_default(bpa->bgp, &(bpa->nh),
|
||||||
AFI_IP,
|
bpa->afi,
|
||||||
bpa->table_id,
|
bpa->table_id,
|
||||||
false);
|
false);
|
||||||
bpa->installed = false;
|
bpa->installed = false;
|
||||||
@ -1794,12 +1837,12 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(
|
|||||||
temp.flags |= MATCH_IP_SRC_SET;
|
temp.flags |= MATCH_IP_SRC_SET;
|
||||||
prefix_copy(&temp2.src, bpf->src);
|
prefix_copy(&temp2.src, bpf->src);
|
||||||
} else
|
} else
|
||||||
temp2.src.family = AF_INET;
|
temp2.src.family = bpf->family;
|
||||||
if (bpf->dst) {
|
if (bpf->dst) {
|
||||||
temp.flags |= MATCH_IP_DST_SET;
|
temp.flags |= MATCH_IP_DST_SET;
|
||||||
prefix_copy(&temp2.dst, bpf->dst);
|
prefix_copy(&temp2.dst, bpf->dst);
|
||||||
} else
|
} else
|
||||||
temp2.dst.family = AF_INET;
|
temp2.dst.family = bpf->family;
|
||||||
if (src_port && (src_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
|
if (src_port && (src_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
|
||||||
if (bpf->protocol == IPPROTO_ICMP)
|
if (bpf->protocol == IPPROTO_ICMP)
|
||||||
temp.flags |= MATCH_ICMP_SET;
|
temp.flags |= MATCH_ICMP_SET;
|
||||||
@ -2200,6 +2243,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
if (nh)
|
if (nh)
|
||||||
memcpy(&temp3.nh, nh, sizeof(struct nexthop));
|
memcpy(&temp3.nh, nh, sizeof(struct nexthop));
|
||||||
temp3.vrf_id = bpf->vrf_id;
|
temp3.vrf_id = bpf->vrf_id;
|
||||||
|
temp3.afi = family2afi(bpf->family);
|
||||||
bpa = hash_get(bgp->pbr_action_hash, &temp3,
|
bpa = hash_get(bgp->pbr_action_hash, &temp3,
|
||||||
bgp_pbr_action_alloc_intern);
|
bgp_pbr_action_alloc_intern);
|
||||||
|
|
||||||
@ -2258,7 +2302,8 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
if (!bpa->installed && !bpa->install_in_progress) {
|
if (!bpa->installed && !bpa->install_in_progress) {
|
||||||
bgp_send_pbr_rule_action(bpa, NULL, true);
|
bgp_send_pbr_rule_action(bpa, NULL, true);
|
||||||
bgp_zebra_announce_default(bgp, nh,
|
bgp_zebra_announce_default(bgp, nh,
|
||||||
AFI_IP, bpa->table_id, true);
|
bpa->afi,
|
||||||
|
bpa->table_id, true);
|
||||||
}
|
}
|
||||||
/* ip rule add */
|
/* ip rule add */
|
||||||
if (bpr && !bpr->installed)
|
if (bpr && !bpr->installed)
|
||||||
@ -2377,11 +2422,11 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
if (bpf->src)
|
if (bpf->src)
|
||||||
prefix_copy(&temp2.src, bpf->src);
|
prefix_copy(&temp2.src, bpf->src);
|
||||||
else
|
else
|
||||||
temp2.src.family = AF_INET;
|
temp2.src.family = bpf->family;
|
||||||
if (bpf->dst)
|
if (bpf->dst)
|
||||||
prefix_copy(&temp2.dst, bpf->dst);
|
prefix_copy(&temp2.dst, bpf->dst);
|
||||||
else
|
else
|
||||||
temp2.dst.family = AF_INET;
|
temp2.dst.family = bpf->family;
|
||||||
temp2.src_port_min = src_port ? src_port->min_port : 0;
|
temp2.src_port_min = src_port ? src_port->min_port : 0;
|
||||||
temp2.dst_port_min = dst_port ? dst_port->min_port : 0;
|
temp2.dst_port_min = dst_port ? dst_port->min_port : 0;
|
||||||
temp2.src_port_max = src_port ? src_port->max_port : 0;
|
temp2.src_port_max = src_port ? src_port->max_port : 0;
|
||||||
@ -2428,7 +2473,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
if (!bpa->installed && !bpa->install_in_progress) {
|
if (!bpa->installed && !bpa->install_in_progress) {
|
||||||
bgp_send_pbr_rule_action(bpa, NULL, true);
|
bgp_send_pbr_rule_action(bpa, NULL, true);
|
||||||
bgp_zebra_announce_default(bgp, nh,
|
bgp_zebra_announce_default(bgp, nh,
|
||||||
AFI_IP, bpa->table_id, true);
|
bpa->afi, bpa->table_id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ipset create */
|
/* ipset create */
|
||||||
@ -2690,6 +2735,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
|
|||||||
bpf.protocol = proto;
|
bpf.protocol = proto;
|
||||||
bpf.src_port = srcp;
|
bpf.src_port = srcp;
|
||||||
bpf.dst_port = dstp;
|
bpf.dst_port = dstp;
|
||||||
|
bpf.family = afi2family(api->afi);
|
||||||
if (!add) {
|
if (!add) {
|
||||||
bgp_pbr_policyroute_remove_from_zebra(bgp, path, &bpf, &bpof);
|
bgp_pbr_policyroute_remove_from_zebra(bgp, path, &bpf, &bpof);
|
||||||
return;
|
return;
|
||||||
@ -2739,10 +2785,18 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case ACTION_REDIRECT_IP:
|
case ACTION_REDIRECT_IP:
|
||||||
nh.type = NEXTHOP_TYPE_IPV4;
|
|
||||||
nh.gate.ipv4.s_addr =
|
|
||||||
api->actions[i].u.zr.redirect_ip_v4.s_addr;
|
|
||||||
nh.vrf_id = api->vrf_id;
|
nh.vrf_id = api->vrf_id;
|
||||||
|
if (api->afi == AFI_IP) {
|
||||||
|
nh.type = NEXTHOP_TYPE_IPV4;
|
||||||
|
nh.gate.ipv4.s_addr =
|
||||||
|
api->actions[i].u.zr.
|
||||||
|
redirect_ip_v4.s_addr;
|
||||||
|
} else {
|
||||||
|
nh.type = NEXTHOP_TYPE_IPV6;
|
||||||
|
memcpy(&nh.gate.ipv6,
|
||||||
|
&api->actions[i].u.zr.redirect_ip_v6,
|
||||||
|
sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
||||||
&nh, &rate);
|
&nh, &rate);
|
||||||
/* XXX combination with REDIRECT_VRF
|
/* XXX combination with REDIRECT_VRF
|
||||||
|
@ -260,6 +260,7 @@ struct bgp_pbr_action {
|
|||||||
bool install_in_progress;
|
bool install_in_progress;
|
||||||
uint32_t refcnt;
|
uint32_t refcnt;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
|
afi_t afi;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct bgp_pbr_rule *bgp_pbr_rule_lookup(vrf_id_t vrf_id,
|
extern struct bgp_pbr_rule *bgp_pbr_rule_lookup(vrf_id_t vrf_id,
|
||||||
|
@ -2356,7 +2356,10 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
|
|||||||
struct bgp_pbr_rule *pbr)
|
struct bgp_pbr_rule *pbr)
|
||||||
{
|
{
|
||||||
struct prefix pfx;
|
struct prefix pfx;
|
||||||
|
uint8_t fam = AF_INET;
|
||||||
|
|
||||||
|
if (pbra && pbra->nh.type == NEXTHOP_TYPE_IPV6)
|
||||||
|
fam = AF_INET6;
|
||||||
stream_putl(s, 0); /* seqno unused */
|
stream_putl(s, 0); /* seqno unused */
|
||||||
if (pbr)
|
if (pbr)
|
||||||
stream_putl(s, pbr->priority);
|
stream_putl(s, pbr->priority);
|
||||||
@ -2376,7 +2379,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
|
|||||||
memcpy(&pfx, &(pbr->src), sizeof(struct prefix));
|
memcpy(&pfx, &(pbr->src), sizeof(struct prefix));
|
||||||
else {
|
else {
|
||||||
memset(&pfx, 0, sizeof(pfx));
|
memset(&pfx, 0, sizeof(pfx));
|
||||||
pfx.family = AF_INET;
|
pfx.family = fam;
|
||||||
}
|
}
|
||||||
stream_putc(s, pfx.family);
|
stream_putc(s, pfx.family);
|
||||||
stream_putc(s, pfx.prefixlen);
|
stream_putc(s, pfx.prefixlen);
|
||||||
@ -2388,7 +2391,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
|
|||||||
memcpy(&pfx, &(pbr->dst), sizeof(struct prefix));
|
memcpy(&pfx, &(pbr->dst), sizeof(struct prefix));
|
||||||
else {
|
else {
|
||||||
memset(&pfx, 0, sizeof(pfx));
|
memset(&pfx, 0, sizeof(pfx));
|
||||||
pfx.family = AF_INET;
|
pfx.family = fam;
|
||||||
}
|
}
|
||||||
stream_putc(s, pfx.family);
|
stream_putc(s, pfx.family);
|
||||||
stream_putc(s, pfx.prefixlen);
|
stream_putc(s, pfx.prefixlen);
|
||||||
@ -3063,14 +3066,14 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
|
|||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
|
|
||||||
if (!nh || nh->type != NEXTHOP_TYPE_IPV4
|
if (!nh || (nh->type != NEXTHOP_TYPE_IPV4
|
||||||
|
&& nh->type != NEXTHOP_TYPE_IPV6)
|
||||||
|| nh->vrf_id == VRF_UNKNOWN)
|
|| nh->vrf_id == VRF_UNKNOWN)
|
||||||
return;
|
return;
|
||||||
memset(&p, 0, sizeof(struct prefix));
|
memset(&p, 0, sizeof(struct prefix));
|
||||||
/* default route */
|
if (afi != AFI_IP && afi != AFI_IP6)
|
||||||
if (afi != AFI_IP)
|
|
||||||
return;
|
return;
|
||||||
p.family = AF_INET;
|
p.family = afi2family(afi);
|
||||||
memset(&api, 0, sizeof(api));
|
memset(&api, 0, sizeof(api));
|
||||||
api.vrf_id = bgp->vrf_id;
|
api.vrf_id = bgp->vrf_id;
|
||||||
api.type = ZEBRA_ROUTE_BGP;
|
api.type = ZEBRA_ROUTE_BGP;
|
||||||
@ -3086,7 +3089,7 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
|
|||||||
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
|
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
|
||||||
|
|
||||||
/* redirect IP */
|
/* redirect IP */
|
||||||
if (nh->gate.ipv4.s_addr != INADDR_ANY) {
|
if (afi == AFI_IP && nh->gate.ipv4.s_addr != INADDR_ANY) {
|
||||||
char buff[PREFIX_STRLEN];
|
char buff[PREFIX_STRLEN];
|
||||||
|
|
||||||
api_nh->vrf_id = nh->vrf_id;
|
api_nh->vrf_id = nh->vrf_id;
|
||||||
@ -3095,7 +3098,25 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
|
|||||||
|
|
||||||
inet_ntop(AF_INET, &(nh->gate.ipv4), buff, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &(nh->gate.ipv4), buff, INET_ADDRSTRLEN);
|
||||||
if (BGP_DEBUG(zebra, ZEBRA))
|
if (BGP_DEBUG(zebra, ZEBRA))
|
||||||
zlog_info("BGP: %s default route to %s table %d (redirect IP)",
|
zlog_debug("BGP: %s default route to %s table %d (redirect IP)",
|
||||||
|
announce ? "adding" : "withdrawing",
|
||||||
|
buff, table_id);
|
||||||
|
zclient_route_send(announce ? ZEBRA_ROUTE_ADD
|
||||||
|
: ZEBRA_ROUTE_DELETE,
|
||||||
|
zclient, &api);
|
||||||
|
} else if (afi == AFI_IP6 &&
|
||||||
|
memcmp(&nh->gate.ipv6,
|
||||||
|
&in6addr_any, sizeof(struct in6_addr))) {
|
||||||
|
char buff[PREFIX_STRLEN];
|
||||||
|
|
||||||
|
api_nh->vrf_id = nh->vrf_id;
|
||||||
|
memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6,
|
||||||
|
sizeof(struct in6_addr));
|
||||||
|
api_nh->type = NEXTHOP_TYPE_IPV6;
|
||||||
|
|
||||||
|
inet_ntop(AF_INET6, &(nh->gate.ipv6), buff, INET_ADDRSTRLEN);
|
||||||
|
if (BGP_DEBUG(zebra, ZEBRA))
|
||||||
|
zlog_debug("BGP: %s default route to %s table %d (redirect IP)",
|
||||||
announce ? "adding" : "withdrawing",
|
announce ? "adding" : "withdrawing",
|
||||||
buff, table_id);
|
buff, table_id);
|
||||||
zclient_route_send(announce ? ZEBRA_ROUTE_ADD
|
zclient_route_send(announce ? ZEBRA_ROUTE_ADD
|
||||||
|
Loading…
Reference in New Issue
Block a user