struct bgp_pbr_rule *bpr_found;
};
-static int bgp_pbr_rule_walkcb(struct hash_backet *backet, void *arg)
+static int bgp_pbr_rule_walkcb(struct hash_bucket *bucket, void *arg)
{
- struct bgp_pbr_rule *bpr = (struct bgp_pbr_rule *)backet->data;
+ struct bgp_pbr_rule *bpr = (struct bgp_pbr_rule *)bucket->data;
struct bgp_pbr_rule_unique *bpru = (struct bgp_pbr_rule_unique *)
arg;
uint32_t unique = bpru->unique;
return HASHWALK_CONTINUE;
}
-static int bgp_pbr_action_walkcb(struct hash_backet *backet, void *arg)
+static int bgp_pbr_action_walkcb(struct hash_bucket *bucket, void *arg)
{
- struct bgp_pbr_action *bpa = (struct bgp_pbr_action *)backet->data;
+ struct bgp_pbr_action *bpa = (struct bgp_pbr_action *)bucket->data;
struct bgp_pbr_action_unique *bpau = (struct bgp_pbr_action_unique *)
arg;
uint32_t unique = bpau->unique;
return HASHWALK_CONTINUE;
}
-static int bgp_pbr_match_entry_walkcb(struct hash_backet *backet, void *arg)
+static int bgp_pbr_match_entry_walkcb(struct hash_bucket *bucket, void *arg)
{
struct bgp_pbr_match_entry *bpme =
- (struct bgp_pbr_match_entry *)backet->data;
+ (struct bgp_pbr_match_entry *)bucket->data;
struct bgp_pbr_match_entry_unique *bpmeu =
(struct bgp_pbr_match_entry_unique *)arg;
uint32_t unique = bpmeu->unique;
struct bgp_pbr_match *bpm_found;
};
-static int bgp_pbr_match_pername_walkcb(struct hash_backet *backet, void *arg)
+static int bgp_pbr_match_pername_walkcb(struct hash_bucket *bucket, void *arg)
{
- struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)backet->data;
+ struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)bucket->data;
struct bgp_pbr_match_ipsetname *bpmi =
(struct bgp_pbr_match_ipsetname *)arg;
char *ipset_name = bpmi->ipsetname;
return HASHWALK_CONTINUE;
}
-static int bgp_pbr_match_iptable_walkcb(struct hash_backet *backet, void *arg)
+static int bgp_pbr_match_iptable_walkcb(struct hash_bucket *bucket, void *arg)
{
- struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)backet->data;
+ struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)bucket->data;
struct bgp_pbr_match_iptable_unique *bpmiu =
(struct bgp_pbr_match_iptable_unique *)arg;
uint32_t unique = bpmiu->unique;
struct bgp_pbr_match *bpm_found;
};
-static int bgp_pbr_match_walkcb(struct hash_backet *backet, void *arg)
+static int bgp_pbr_match_walkcb(struct hash_bucket *bucket, void *arg)
{
- struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)backet->data;
+ struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)bucket->data;
struct bgp_pbr_match_unique *bpmu = (struct bgp_pbr_match_unique *)
arg;
uint32_t unique = bpmu->unique;
unary_operator, and_valmask,
or_valmask, list[i].value,
type_entry);
- if (ret == false)
+ if (!ret)
return ret;
continue;
}
range->min_port = list[i].value;
exact_match = true;
}
- if (exact_match == true && i > 0)
+ if (exact_match && i > 0)
return false;
if (list[i].compare_operator ==
(OPERATOR_COMPARE_GREATER_THAN +
"too complex. ignoring.");
return 0;
} else if (api->match_icmp_type_num > 1 &&
- enumerate_icmp == false) {
+ !enumerate_icmp) {
if (BGP_DEBUG(pbr, PBR))
zlog_debug("BGP: match icmp code is enumerate"
", and icmp type is not."
int valid_prefix = 0;
afi_t afi = AFI_IP;
struct bgp_pbr_entry_action *api_action_redirect_ip = NULL;
+ bool discard_action_found = false;
/* extract match from flowspec entries */
ret = bgp_flowspec_match_rules_fill((uint8_t *)p->u.prefix_flowspec.ptr,
if (ret < 0)
return -1;
/* extract actiosn from flowspec ecom list */
- if (path && path->attr && path->attr->ecommunity) {
+ if (path && path->attr->ecommunity) {
ecom = path->attr->ecommunity;
for (i = 0; i < ecom->size; i++) {
ecom_eval = (struct ecommunity_val *)
api_action);
if (ret != 0)
continue;
+ if ((api_action->action == ACTION_TRAFFICRATE) &&
+ api->actions[i].u.r.rate == 0)
+ discard_action_found = true;
}
api->action_num++;
}
}
+ /* if ECOMMUNITY_TRAFFIC_RATE = 0 as action
+ * then reduce the API action list to that action
+ */
+ if (api->action_num > 1 && discard_action_found) {
+ api->action_num = 1;
+ memset(&api->actions[0], 0,
+ sizeof(struct bgp_pbr_entry_action));
+ api->actions[0].action = ACTION_TRAFFICRATE;
+ }
/* validate if incoming matc/action is compatible
* with our policy routing engine
return new;
}
-uint32_t bgp_pbr_match_hash_key(void *arg)
+uint32_t bgp_pbr_match_hash_key(const void *arg)
{
- struct bgp_pbr_match *pbm = (struct bgp_pbr_match *)arg;
+ const struct bgp_pbr_match *pbm = arg;
uint32_t key;
key = jhash_1word(pbm->vrf_id, 0x4312abde);
key = jhash(&pbm->tcp_mask_flags, 2, key);
key = jhash(&pbm->dscp_value, 1, key);
key = jhash(&pbm->fragment, 1, key);
+ key = jhash(&pbm->protocol, 1, key);
return jhash_1word(pbm->type, key);
}
if (r1->fragment != r2->fragment)
return false;
+
+ if (r1->protocol != r2->protocol)
+ return false;
return true;
}
-uint32_t bgp_pbr_rule_hash_key(void *arg)
+uint32_t bgp_pbr_rule_hash_key(const void *arg)
{
- struct bgp_pbr_rule *pbr = (struct bgp_pbr_rule *)arg;
+ const struct bgp_pbr_rule *pbr = arg;
uint32_t key;
key = prefix_hash_key(&pbr->src);
return true;
}
-uint32_t bgp_pbr_match_entry_hash_key(void *arg)
+uint32_t bgp_pbr_match_entry_hash_key(const void *arg)
{
- struct bgp_pbr_match_entry *pbme;
+ const struct bgp_pbr_match_entry *pbme;
uint32_t key;
- pbme = (struct bgp_pbr_match_entry *)arg;
+ pbme = arg;
key = prefix_hash_key(&pbme->src);
key = jhash_1word(prefix_hash_key(&pbme->dst), key);
key = jhash(&pbme->dst_port_min, 2, key);
return true;
}
-uint32_t bgp_pbr_action_hash_key(void *arg)
+uint32_t bgp_pbr_action_hash_key(const void *arg)
{
- struct bgp_pbr_action *pbra;
+ const struct bgp_pbr_action *pbra;
uint32_t key;
- pbra = (struct bgp_pbr_action *)arg;
+ pbra = arg;
key = jhash_1word(pbra->table_id, 0x4312abde);
key = jhash_1word(pbra->fwmark, key);
return key;
bpr->installed = false;
bpr->action->refcnt--;
bpr->action = NULL;
+ if (bpr->path) {
+ struct bgp_path_info *path;
+ struct bgp_path_info_extra *extra;
+
+ /* unlink path to bpme */
+ path = (struct bgp_path_info *)bpr->path;
+ extra = bgp_path_info_extra_get(path);
+ if (extra->bgp_fs_iprule)
+ listnode_delete(extra->bgp_fs_iprule, bpr);
+ bpr->path = NULL;
+ }
}
hash_release(bgp->pbr_rule_hash, bpr);
if (bpa->refcnt == 0) {
struct bgp_path_info *path;
struct bgp_path_info_extra *extra;
- /* unlink bgp_path_info to bpme */
+ /* unlink path to bpme */
path = (struct bgp_path_info *)bpme->path;
extra = bgp_path_info_extra_get(path);
if (extra->bgp_fs_pbr)
struct bgp_pbr_rule *bpr_found;
};
-static int bgp_pbr_get_same_rule(struct hash_backet *backet, void *arg)
+static int bgp_pbr_get_same_rule(struct hash_bucket *bucket, void *arg)
{
- struct bgp_pbr_rule *r1 = (struct bgp_pbr_rule *)backet->data;
+ struct bgp_pbr_rule *r1 = (struct bgp_pbr_rule *)bucket->data;
struct bgp_pbr_rule_remain *ctxt =
(struct bgp_pbr_rule_remain *)arg;
struct bgp_pbr_rule *r2;
return HASHWALK_CONTINUE;
}
-static int bgp_pbr_get_remaining_entry(struct hash_backet *backet, void *arg)
+static int bgp_pbr_get_remaining_entry(struct hash_bucket *bucket, void *arg)
{
- struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)backet->data;
+ struct bgp_pbr_match *bpm = (struct bgp_pbr_match *)bucket->data;
struct bgp_pbr_match_entry_remain *bpmer =
(struct bgp_pbr_match_entry_remain *)arg;
struct bgp_pbr_match *bpm_temp;
temp.type = IPSET_NET_NET;
}
if (bpf->vrf_id == VRF_UNKNOWN) /* XXX case BGP destroy */
- temp.vrf_id = 0;
+ temp.vrf_id = VRF_DEFAULT;
else
temp.vrf_id = bpf->vrf_id;
bpme = &temp2;
struct bgp_pbr_range_port *pkt_len;
struct bgp_pbr_rule pbr_rule;
struct bgp_pbr_rule *bpr;
+ bool bpr_found = false;
bool bpme_found = false;
if (!bpf)
bpr->unique = ++bgp_pbr_action_counter_unique;
bpr->installed = false;
bpr->install_in_progress = false;
+ /* link bgp info to bpr */
+ bpr->path = (void *)path;
+ } else
+ bpr_found = true;
+ /* already installed */
+ if (bpr_found && bpr) {
+ struct bgp_path_info_extra *extra =
+ bgp_path_info_extra_get(path);
+
+ if (extra &&
+ listnode_lookup_nocheck(extra->bgp_fs_iprule,
+ bpr)) {
+ if (BGP_DEBUG(pbr, PBR_ERROR))
+ zlog_err("%s: entry %p/%p already "
+ "installed in bgp pbr iprule",
+ __func__, path, bpr);
+ return;
+ }
}
if (!bpa->installed && !bpa->install_in_progress) {
bgp_send_pbr_rule_action(bpa, NULL, true);
temp.flags |= MATCH_FRAGMENT_INVERSE_SET;
temp.fragment = bpf->fragment->val;
}
+ if (bpf->protocol) {
+ temp.protocol = bpf->protocol;
+ temp.flags |= MATCH_PROTOCOL_SET;
+ }
temp.action = bpa;
bpm = hash_get(bgp->pbr_match_hash, &temp,
bgp_pbr_match_alloc_intern);
struct bgp_path_info_extra *extra =
bgp_path_info_extra_get(path);
- if (extra && extra->bgp_fs_pbr &&
- listnode_lookup(extra->bgp_fs_pbr, bpme)) {
+ if (extra &&
+ listnode_lookup_nocheck(extra->bgp_fs_pbr, bpme)) {
if (BGP_DEBUG(pbr, PBR_ERROR))
zlog_err(
"%s: entry %p/%p already installed in bgp pbr",