static inline int tcf_simp_cleanup(struct tc_action *a, int bind) { struct tcf_defact *d = a->priv; if (d) return tcf_simp_release(d, bind); return 0; }
static int tcf_simp_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, int ovr, int bind) { struct rtattr *tb[TCA_DEF_MAX]; struct tc_defact *parm; struct tcf_defact *d; struct tcf_common *pc; void *defdata; u32 datalen = 0; int ret = 0; if (rta == NULL || rtattr_parse_nested(tb, TCA_DEF_MAX, rta) < 0) return -EINVAL; if (tb[TCA_DEF_PARMS - 1] == NULL || RTA_PAYLOAD(tb[TCA_DEF_PARMS - 1]) < sizeof(*parm)) return -EINVAL; parm = RTA_DATA(tb[TCA_DEF_PARMS - 1]); defdata = RTA_DATA(tb[TCA_DEF_DATA - 1]); if (defdata == NULL) return -EINVAL; datalen = RTA_PAYLOAD(tb[TCA_DEF_DATA - 1]); if (datalen <= 0) return -EINVAL; pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, &simp_idx_gen, &simp_hash_info); if (unlikely(!pc)) return -ENOMEM; d = to_defact(pc); ret = alloc_defdata(d, datalen, defdata); if (ret < 0) { kfree(pc); return ret; } ret = ACT_P_CREATED; } else { d = to_defact(pc); if (!ovr) { tcf_simp_release(d, bind); return -EEXIST; } realloc_defdata(d, datalen, defdata); } spin_lock_bh(&d->tcf_lock); d->tcf_action = parm->action; spin_unlock_bh(&d->tcf_lock); if (ret == ACT_P_CREATED) tcf_hash_insert(pc, &simp_hash_info); return ret; }
static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, struct tc_action *a, int ovr, int bind) { struct nlattr *tb[TCA_DEF_MAX + 1]; struct tc_defact *parm; struct tcf_defact *d; struct tcf_common *pc; char *defdata; int ret = 0, err; if (nla == NULL) return -EINVAL; err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy); if (err < 0) return err; if (tb[TCA_DEF_PARMS] == NULL) return -EINVAL; if (tb[TCA_DEF_DATA] == NULL) return -EINVAL; parm = nla_data(tb[TCA_DEF_PARMS]); defdata = nla_data(tb[TCA_DEF_DATA]); pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, &simp_idx_gen, &simp_hash_info); if (unlikely(!pc)) return -ENOMEM; d = to_defact(pc); ret = alloc_defdata(d, defdata); if (ret < 0) { kfree(pc); return ret; } d->tcf_action = parm->action; ret = ACT_P_CREATED; } else { d = to_defact(pc); if (!ovr) { tcf_simp_release(d, bind); return -EEXIST; } reset_policy(d, defdata, parm); } if (ret == ACT_P_CREATED) tcf_hash_insert(pc, &simp_hash_info); return ret; }