return HASHWALK_ABORT;
}
-static void bgp_pbr_policyroute_remove_from_zebra(struct bgp *bgp,
+static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
struct bgp_info *binfo,
struct bgp_pbr_filter *bpf)
{
}
}
-static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
+static void bgp_pbr_policyroute_remove_from_zebra(struct bgp *bgp,
+ struct bgp_info *binfo,
+ struct bgp_pbr_filter *bpf,
+ struct bgp_pbr_or_filter *bpof)
+{
+ if (bpof && bpof->tcpflags) {
+ struct listnode *node, *nnode;
+ struct bgp_pbr_val_mask *valmask;
+
+ for (ALL_LIST_ELEMENTS(bpof->tcpflags, node, nnode, valmask)) {
+ bpf->tcp_flags = valmask;
+ bgp_pbr_policyroute_remove_from_zebra_unit(bgp, binfo, bpf);
+ XFREE(MTYPE_PBR_VALMASK, valmask);
+ listnode_delete(bpof->tcpflags, node);
+ }
+ list_delete_all_node(bpof->tcpflags);
+ bpof->tcpflags = NULL;
+ } else
+ bgp_pbr_policyroute_remove_from_zebra_unit(bgp, binfo, bpf);
+}
+
+static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
struct bgp_info *binfo,
struct bgp_pbr_filter *bpf,
struct nexthop *nh,
}
+static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
+ struct bgp_info *binfo,
+ struct bgp_pbr_filter *bpf,
+ struct bgp_pbr_or_filter *bpof,
+ struct nexthop *nh,
+ float *rate)
+{
+ if (bpof && bpof->tcpflags) {
+ struct listnode *node, *nnode;
+ struct bgp_pbr_val_mask *valmask;
+
+ for (ALL_LIST_ELEMENTS(bpof->tcpflags, node, nnode, valmask)) {
+ bpf->tcp_flags = valmask;
+ bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo, bpf, nh, rate);
+ XFREE(MTYPE_PBR_VALMASK, valmask);
+ listnode_delete(bpof->tcpflags, node);
+ }
+ list_delete_all_node(bpof->tcpflags);
+ bpof->tcpflags = NULL;
+ } else
+ return bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo,
+ bpf, nh, rate);
+}
+
static const struct message icmp_code_unreach_str[] = {
{ 9, "communication-prohibited-by-filtering"},
{ 10, "destination-host-prohibited"},
dstp.min_port = dst[0].value;
if (add)
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
- bpf, nh, rate);
+ bpf, NULL, nh, rate);
else
bgp_pbr_policyroute_remove_from_zebra(bgp,
- binfo, bpf);
+ binfo, bpf, NULL);
return;
}
/* parse icmp type and lookup appropriate icmp code
icmp_typecode_configured = true;
if (add)
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
- bpf, nh, rate);
+ bpf, NULL,
+ nh, rate);
else
bgp_pbr_policyroute_remove_from_zebra(
- bgp, binfo, bpf);
+ bgp, binfo, bpf, NULL);
}
}
/* create a list of ICMP type/code combinatories */
dstp.min_port = pnt->key;
if (add)
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
- bpf, nh, rate);
+ bpf, NULL, nh, rate);
else
bgp_pbr_policyroute_remove_from_zebra(bgp,
- binfo, bpf);
+ binfo, bpf, NULL);
}
}
dstp.min_port = 0;
if (add)
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
- bpf, nh, rate);
+ bpf, NULL, nh, rate);
else
bgp_pbr_policyroute_remove_from_zebra(bgp,
- binfo, bpf);
+ binfo, bpf, NULL);
break;
}
}
struct bgp_pbr_filter bpf;
uint8_t kind_enum;
struct bgp_pbr_or_filter bpof;
+ struct bgp_pbr_val_mask bpvm;
memset(&nh, 0, sizeof(struct nexthop));
memset(&bpf, 0, sizeof(struct bgp_pbr_filter));
kind_enum = bgp_pbr_match_val_get_operator(api->tcpflags,
api->match_tcpflags_num);
if (kind_enum == OPERATOR_UNARY_AND) {
+ bpf.tcp_flags = &bpvm;
bgp_pbr_extract_enumerate(api->tcpflags,
api->match_tcpflags_num,
OPERATOR_UNARY_AND, bpf.tcp_flags);
}
return bgp_pbr_policyroute_remove_from_zebra(bgp,
binfo,
- &bpf);
+ &bpf, &bpof);
}
/* no action for add = true */
for (i = 0; i < api->action_num; i++) {
&nh, &rate);
else
bgp_pbr_policyroute_add_to_zebra(bgp, binfo, &bpf,
- &nh, &rate);
+ &bpof, &nh, &rate);
} else {
/* update rate. can be reentrant */
rate = api->actions[i].u.r.rate;
&bpf, bgp, binfo, add,
&nh, &rate);
else
- bgp_pbr_policyroute_add_to_zebra(bgp, binfo, &bpf,
+ bgp_pbr_policyroute_add_to_zebra(bgp, binfo, &bpf, &bpof,
&nh, &rate);
/* XXX combination with REDIRECT_VRF
* + REDIRECT_NH_IP not done
&nh, &rate);
else
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
- &bpf, &nh, &rate);
+ &bpf, &bpof, &nh, &rate);
continue_loop = 0;
break;
case ACTION_MARKING: