#include <net/sch_generic.h>
#include <net/act_api.h>
-#if 1 /* control */
+#if 0 /* control */
#define DPRINTK(format, args...) printk(KERN_DEBUG format, ##args)
#else
#define DPRINTK(format, args...)
while ((a = act) != NULL) {
repeat:
if (a->ops && a->ops->act) {
- ret = a->ops->act(&skb, a);
+ ret = a->ops->act(skb, a, res);
if (TC_MUNGED & skb->tc_verd) {
/* copied already, allow trampling */
skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
}
- if (ret != TC_ACT_PIPE)
- goto exec_done;
if (ret == TC_ACT_REPEAT)
goto repeat; /* we need a ttl - JHS */
+ if (ret != TC_ACT_PIPE)
+ goto exec_done;
}
act = a->next;
}
exec_done:
- if (skb->tc_classid > 0) {
- res->classid = skb->tc_classid;
- res->class = 0;
- skb->tc_classid = 0;
- }
return ret;
}
return err;
RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
- if (tcf_action_copy_stats(skb, a))
+ if (tcf_action_copy_stats(skb, a, 0))
goto rtattr_failure;
r = (struct rtattr*) skb->tail;
RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
RTA_PUT(skb, a->order, 0, NULL);
err = tcf_action_dump_1(skb, a, bind, ref);
if (err < 0)
- goto rtattr_failure;
+ goto errout;
r->rta_len = skb->tail - (u8*)r;
}
return 0;
rtattr_failure:
+ err = -EINVAL;
+errout:
skb_trim(skb, b - skb->data);
- return -err;
+ return err;
}
struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
if (a_o == NULL) {
#ifdef CONFIG_KMOD
rtnl_unlock();
- request_module(act_name);
+ request_module("act_%s", act_name);
rtnl_lock();
a_o = tc_lookup_action_n(act_name);
goto err_mod;
}
#endif
+ *err = -ENOENT;
goto err_out;
}
return NULL;
}
-int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a)
+int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
+ int compat_mode)
{
- int err;
+ int err = 0;
struct gnet_dump d;
struct tcf_act_hdr *h = a->priv;
if (h == NULL)
goto errout;
- if (a->type == TCA_OLD_COMPAT)
- err = gnet_stats_start_copy_compat(skb, TCA_ACT_STATS,
- TCA_STATS, TCA_XSTATS, h->stats_lock, &d);
- else
+ /* compat_mode being true specifies a call that is supposed
+ * to add additional backward compatiblity statistic TLVs.
+ */
+ if (compat_mode) {
+ if (a->type == TCA_OLD_COMPAT)
+ err = gnet_stats_start_copy_compat(skb, 0,
+ TCA_STATS, TCA_XSTATS, h->stats_lock, &d);
+ else
+ return 0;
+ } else
err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
h->stats_lock, &d);
static int
tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
- unsigned flags, int event, int bind, int ref)
+ u16 flags, int event, int bind, int ref)
{
struct tcamsg *t;
struct nlmsghdr *nlh;
unsigned char *b = skb->tail;
struct rtattr *x;
- nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
- nlh->nlmsg_flags = flags;
+ nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
+
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
+ t->tca__pad1 = 0;
+ t->tca__pad2 = 0;
x = (struct rtattr*) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
+ t->tca__pad1 = 0;
+ t->tca__pad2 = 0;
x = (struct rtattr *) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
nlh->nlmsg_flags |= NLM_F_ROOT;
module_put(a->ops->owner);
kfree(a);
- err = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+ err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
if (err > 0)
return 0;
return err;
rtattr_failure:
- module_put(a->ops->owner);
nlmsg_failure:
+ module_put(a->ops->owner);
err_out:
kfree_skb(skb);
kfree(a);
/* now do the delete */
tcf_action_destroy(head, 0);
- ret = rtnetlink_send(skb, pid, RTMGRP_TC,
+ ret = rtnetlink_send(skb, pid, RTNLGRP_TC,
n->nlmsg_flags&NLM_F_ECHO);
if (ret > 0)
return 0;
}
static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
- unsigned flags)
+ u16 flags)
{
struct tcamsg *t;
struct nlmsghdr *nlh;
b = (unsigned char *)skb->tail;
- nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
- nlh->nlmsg_flags = flags;
+ nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
-
+ t->tca__pad1 = 0;
+ t->tca__pad2 = 0;
+
x = (struct rtattr*) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
x->rta_len = skb->tail - (u8*)x;
nlh->nlmsg_len = skb->tail - b;
- NETLINK_CB(skb).dst_groups = RTMGRP_TC;
+ NETLINK_CB(skb).dst_group = RTNLGRP_TC;
- err = rtnetlink_send(skb, pid, RTMGRP_TC, flags&NLM_F_ECHO);
+ err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
if (err > 0)
err = 0;
return err;
rtattr_failure:
nlmsg_failure:
- skb_trim(skb, b - skb->data);
+ kfree_skb(skb);
return -1;
}
return ret;
}
-static char *
+static struct rtattr *
find_dump_kind(struct nlmsghdr *n)
{
struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
return NULL;
kind = tb2[TCA_ACT_KIND-1];
- return (char *) RTA_DATA(kind);
+ return kind;
}
static int
struct tc_action a;
int ret = 0;
struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
- char *kind = find_dump_kind(cb->nlh);
+ struct rtattr *kind = find_dump_kind(cb->nlh);
if (kind == NULL) {
printk("tc_dump_action: action bad kind\n");
return 0;
}
- a_o = tc_lookup_action_n(kind);
+ a_o = tc_lookup_action(kind);
if (a_o == NULL) {
- printk("failed to find %s\n", kind);
return 0;
}
a.ops = a_o;
if (a_o->walk == NULL) {
- printk("tc_dump_action: %s !capable of dumping table\n", kind);
+ printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind);
goto rtattr_failure;
}
cb->nlh->nlmsg_type, sizeof(*t));
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
+ t->tca__pad1 = 0;
+ t->tca__pad2 = 0;
x = (struct rtattr *) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
}
- printk("TC classifier action (bugs to netdev@oss.sgi.com cc "
- "hadi@cyberus.ca)\n");
return 0;
}