linux/net/sched/act_api.c
<<
>>
Prefs
   1/*
   2 * net/sched/act_api.c  Packet action API.
   3 *
   4 *              This program is free software; you can redistribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 * Author:      Jamal Hadi Salim
  10 *
  11 *
  12 */
  13
  14#include <linux/types.h>
  15#include <linux/kernel.h>
  16#include <linux/string.h>
  17#include <linux/errno.h>
  18#include <linux/skbuff.h>
  19#include <linux/init.h>
  20#include <linux/kmod.h>
  21#include <linux/err.h>
  22#include <net/net_namespace.h>
  23#include <net/sock.h>
  24#include <net/sch_generic.h>
  25#include <net/act_api.h>
  26#include <net/netlink.h>
  27
  28void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
  29{
  30        unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
  31        struct tcf_common **p1p;
  32
  33        for (p1p = &hinfo->htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) {
  34                if (*p1p == p) {
  35                        write_lock_bh(hinfo->lock);
  36                        *p1p = p->tcfc_next;
  37                        write_unlock_bh(hinfo->lock);
  38                        gen_kill_estimator(&p->tcfc_bstats,
  39                                           &p->tcfc_rate_est);
  40                        kfree(p);
  41                        return;
  42                }
  43        }
  44        WARN_ON(1);
  45}
  46EXPORT_SYMBOL(tcf_hash_destroy);
  47
  48int tcf_hash_release(struct tcf_common *p, int bind,
  49                     struct tcf_hashinfo *hinfo)
  50{
  51        int ret = 0;
  52
  53        if (p) {
  54                if (bind)
  55                        p->tcfc_bindcnt--;
  56
  57                p->tcfc_refcnt--;
  58                if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) {
  59                        tcf_hash_destroy(p, hinfo);
  60                        ret = 1;
  61                }
  62        }
  63        return ret;
  64}
  65EXPORT_SYMBOL(tcf_hash_release);
  66
  67static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
  68                           struct tc_action *a, struct tcf_hashinfo *hinfo)
  69{
  70        struct tcf_common *p;
  71        int err = 0, index = -1,i = 0, s_i = 0, n_i = 0;
  72        struct nlattr *nest;
  73
  74        read_lock_bh(hinfo->lock);
  75
  76        s_i = cb->args[0];
  77
  78        for (i = 0; i < (hinfo->hmask + 1); i++) {
  79                p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
  80
  81                for (; p; p = p->tcfc_next) {
  82                        index++;
  83                        if (index < s_i)
  84                                continue;
  85                        a->priv = p;
  86                        a->order = n_i;
  87
  88                        nest = nla_nest_start(skb, a->order);
  89                        if (nest == NULL)
  90                                goto nla_put_failure;
  91                        err = tcf_action_dump_1(skb, a, 0, 0);
  92                        if (err < 0) {
  93                                index--;
  94                                nlmsg_trim(skb, nest);
  95                                goto done;
  96                        }
  97                        nla_nest_end(skb, nest);
  98                        n_i++;
  99                        if (n_i >= TCA_ACT_MAX_PRIO)
 100                                goto done;
 101                }
 102        }
 103done:
 104        read_unlock_bh(hinfo->lock);
 105        if (n_i)
 106                cb->args[0] += n_i;
 107        return n_i;
 108
 109nla_put_failure:
 110        nla_nest_cancel(skb, nest);
 111        goto done;
 112}
 113
 114static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
 115                          struct tcf_hashinfo *hinfo)
 116{
 117        struct tcf_common *p, *s_p;
 118        struct nlattr *nest;
 119        int i= 0, n_i = 0;
 120
 121        nest = nla_nest_start(skb, a->order);
 122        if (nest == NULL)
 123                goto nla_put_failure;
 124        NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
 125        for (i = 0; i < (hinfo->hmask + 1); i++) {
 126                p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
 127
 128                while (p != NULL) {
 129                        s_p = p->tcfc_next;
 130                        if (ACT_P_DELETED == tcf_hash_release(p, 0, hinfo))
 131                                 module_put(a->ops->owner);
 132                        n_i++;
 133                        p = s_p;
 134                }
 135        }
 136        NLA_PUT_U32(skb, TCA_FCNT, n_i);
 137        nla_nest_end(skb, nest);
 138
 139        return n_i;
 140nla_put_failure:
 141        nla_nest_cancel(skb, nest);
 142        return -EINVAL;
 143}
 144
 145int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
 146                       int type, struct tc_action *a)
 147{
 148        struct tcf_hashinfo *hinfo = a->ops->hinfo;
 149
 150        if (type == RTM_DELACTION) {
 151                return tcf_del_walker(skb, a, hinfo);
 152        } else if (type == RTM_GETACTION) {
 153                return tcf_dump_walker(skb, cb, a, hinfo);
 154        } else {
 155                printk("tcf_generic_walker: unknown action %d\n", type);
 156                return -EINVAL;
 157        }
 158}
 159EXPORT_SYMBOL(tcf_generic_walker);
 160
 161struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo)
 162{
 163        struct tcf_common *p;
 164
 165        read_lock_bh(hinfo->lock);
 166        for (p = hinfo->htab[tcf_hash(index, hinfo->hmask)]; p;
 167             p = p->tcfc_next) {
 168                if (p->tcfc_index == index)
 169                        break;
 170        }
 171        read_unlock_bh(hinfo->lock);
 172
 173        return p;
 174}
 175EXPORT_SYMBOL(tcf_hash_lookup);
 176
 177u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo)
 178{
 179        u32 val = *idx_gen;
 180
 181        do {
 182                if (++val == 0)
 183                        val = 1;
 184        } while (tcf_hash_lookup(val, hinfo));
 185
 186        return (*idx_gen = val);
 187}
 188EXPORT_SYMBOL(tcf_hash_new_index);
 189
 190int tcf_hash_search(struct tc_action *a, u32 index)
 191{
 192        struct tcf_hashinfo *hinfo = a->ops->hinfo;
 193        struct tcf_common *p = tcf_hash_lookup(index, hinfo);
 194
 195        if (p) {
 196                a->priv = p;
 197                return 1;
 198        }
 199        return 0;
 200}
 201EXPORT_SYMBOL(tcf_hash_search);
 202
 203struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind,
 204                                  struct tcf_hashinfo *hinfo)
 205{
 206        struct tcf_common *p = NULL;
 207        if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) {
 208                if (bind)
 209                        p->tcfc_bindcnt++;
 210                p->tcfc_refcnt++;
 211                a->priv = p;
 212        }
 213        return p;
 214}
 215EXPORT_SYMBOL(tcf_hash_check);
 216
 217struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est,
 218                                   struct tc_action *a, int size, int bind,
 219                                   u32 *idx_gen, struct tcf_hashinfo *hinfo)
 220{
 221        struct tcf_common *p = kzalloc(size, GFP_KERNEL);
 222
 223        if (unlikely(!p))
 224                return ERR_PTR(-ENOMEM);
 225        p->tcfc_refcnt = 1;
 226        if (bind)
 227                p->tcfc_bindcnt = 1;
 228
 229        spin_lock_init(&p->tcfc_lock);
 230        p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo);
 231        p->tcfc_tm.install = jiffies;
 232        p->tcfc_tm.lastuse = jiffies;
 233        if (est) {
 234                int err = gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est,
 235                                            &p->tcfc_lock, est);
 236                if (err) {
 237                        kfree(p);
 238                        return ERR_PTR(err);
 239                }
 240        }
 241
 242        a->priv = (void *) p;
 243        return p;
 244}
 245EXPORT_SYMBOL(tcf_hash_create);
 246
 247void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo)
 248{
 249        unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
 250
 251        write_lock_bh(hinfo->lock);
 252        p->tcfc_next = hinfo->htab[h];
 253        hinfo->htab[h] = p;
 254        write_unlock_bh(hinfo->lock);
 255}
 256EXPORT_SYMBOL(tcf_hash_insert);
 257
 258static struct tc_action_ops *act_base = NULL;
 259static DEFINE_RWLOCK(act_mod_lock);
 260
 261int tcf_register_action(struct tc_action_ops *act)
 262{
 263        struct tc_action_ops *a, **ap;
 264
 265        write_lock(&act_mod_lock);
 266        for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) {
 267                if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) {
 268                        write_unlock(&act_mod_lock);
 269                        return -EEXIST;
 270                }
 271        }
 272        act->next = NULL;
 273        *ap = act;
 274        write_unlock(&act_mod_lock);
 275        return 0;
 276}
 277EXPORT_SYMBOL(tcf_register_action);
 278
 279int tcf_unregister_action(struct tc_action_ops *act)
 280{
 281        struct tc_action_ops *a, **ap;
 282        int err = -ENOENT;
 283
 284        write_lock(&act_mod_lock);
 285        for (ap = &act_base; (a = *ap) != NULL; ap = &a->next)
 286                if (a == act)
 287                        break;
 288        if (a) {
 289                *ap = a->next;
 290                a->next = NULL;
 291                err = 0;
 292        }
 293        write_unlock(&act_mod_lock);
 294        return err;
 295}
 296EXPORT_SYMBOL(tcf_unregister_action);
 297
 298/* lookup by name */
 299static struct tc_action_ops *tc_lookup_action_n(char *kind)
 300{
 301        struct tc_action_ops *a = NULL;
 302
 303        if (kind) {
 304                read_lock(&act_mod_lock);
 305                for (a = act_base; a; a = a->next) {
 306                        if (strcmp(kind, a->kind) == 0) {
 307                                if (!try_module_get(a->owner)) {
 308                                        read_unlock(&act_mod_lock);
 309                                        return NULL;
 310                                }
 311                                break;
 312                        }
 313                }
 314                read_unlock(&act_mod_lock);
 315        }
 316        return a;
 317}
 318
 319/* lookup by nlattr */
 320static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
 321{
 322        struct tc_action_ops *a = NULL;
 323
 324        if (kind) {
 325                read_lock(&act_mod_lock);
 326                for (a = act_base; a; a = a->next) {
 327                        if (nla_strcmp(kind, a->kind) == 0) {
 328                                if (!try_module_get(a->owner)) {
 329                                        read_unlock(&act_mod_lock);
 330                                        return NULL;
 331                                }
 332                                break;
 333                        }
 334                }
 335                read_unlock(&act_mod_lock);
 336        }
 337        return a;
 338}
 339
 340#if 0
 341/* lookup by id */
 342static struct tc_action_ops *tc_lookup_action_id(u32 type)
 343{
 344        struct tc_action_ops *a = NULL;
 345
 346        if (type) {
 347                read_lock(&act_mod_lock);
 348                for (a = act_base; a; a = a->next) {
 349                        if (a->type == type) {
 350                                if (!try_module_get(a->owner)) {
 351                                        read_unlock(&act_mod_lock);
 352                                        return NULL;
 353                                }
 354                                break;
 355                        }
 356                }
 357                read_unlock(&act_mod_lock);
 358        }
 359        return a;
 360}
 361#endif
 362
 363int tcf_action_exec(struct sk_buff *skb, struct tc_action *act,
 364                    struct tcf_result *res)
 365{
 366        struct tc_action *a;
 367        int ret = -1;
 368
 369        if (skb->tc_verd & TC_NCLS) {
 370                skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
 371                ret = TC_ACT_OK;
 372                goto exec_done;
 373        }
 374        while ((a = act) != NULL) {
 375repeat:
 376                if (a->ops && a->ops->act) {
 377                        ret = a->ops->act(skb, a, res);
 378                        if (TC_MUNGED & skb->tc_verd) {
 379                                /* copied already, allow trampling */
 380                                skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
 381                                skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
 382                        }
 383                        if (ret == TC_ACT_REPEAT)
 384                                goto repeat;    /* we need a ttl - JHS */
 385                        if (ret != TC_ACT_PIPE)
 386                                goto exec_done;
 387                }
 388                act = a->next;
 389        }
 390exec_done:
 391        return ret;
 392}
 393EXPORT_SYMBOL(tcf_action_exec);
 394
 395void tcf_action_destroy(struct tc_action *act, int bind)
 396{
 397        struct tc_action *a;
 398
 399        for (a = act; a; a = act) {
 400                if (a->ops && a->ops->cleanup) {
 401                        if (a->ops->cleanup(a, bind) == ACT_P_DELETED)
 402                                module_put(a->ops->owner);
 403                        act = act->next;
 404                        kfree(a);
 405                } else { /*FIXME: Remove later - catch insertion bugs*/
 406                        printk("tcf_action_destroy: BUG? destroying NULL ops\n");
 407                        act = act->next;
 408                        kfree(a);
 409                }
 410        }
 411}
 412
 413int
 414tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 415{
 416        int err = -EINVAL;
 417
 418        if (a->ops == NULL || a->ops->dump == NULL)
 419                return err;
 420        return a->ops->dump(skb, a, bind, ref);
 421}
 422
 423int
 424tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 425{
 426        int err = -EINVAL;
 427        unsigned char *b = skb_tail_pointer(skb);
 428        struct nlattr *nest;
 429
 430        if (a->ops == NULL || a->ops->dump == NULL)
 431                return err;
 432
 433        NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
 434        if (tcf_action_copy_stats(skb, a, 0))
 435                goto nla_put_failure;
 436        nest = nla_nest_start(skb, TCA_OPTIONS);
 437        if (nest == NULL)
 438                goto nla_put_failure;
 439        if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) {
 440                nla_nest_end(skb, nest);
 441                return err;
 442        }
 443
 444nla_put_failure:
 445        nlmsg_trim(skb, b);
 446        return -1;
 447}
 448EXPORT_SYMBOL(tcf_action_dump_1);
 449
 450int
 451tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
 452{
 453        struct tc_action *a;
 454        int err = -EINVAL;
 455        struct nlattr *nest;
 456
 457        while ((a = act) != NULL) {
 458                act = a->next;
 459                nest = nla_nest_start(skb, a->order);
 460                if (nest == NULL)
 461                        goto nla_put_failure;
 462                err = tcf_action_dump_1(skb, a, bind, ref);
 463                if (err < 0)
 464                        goto errout;
 465                nla_nest_end(skb, nest);
 466        }
 467
 468        return 0;
 469
 470nla_put_failure:
 471        err = -EINVAL;
 472errout:
 473        nla_nest_cancel(skb, nest);
 474        return err;
 475}
 476
 477struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
 478                                    char *name, int ovr, int bind)
 479{
 480        struct tc_action *a;
 481        struct tc_action_ops *a_o;
 482        char act_name[IFNAMSIZ];
 483        struct nlattr *tb[TCA_ACT_MAX+1];
 484        struct nlattr *kind;
 485        int err;
 486
 487        if (name == NULL) {
 488                err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
 489                if (err < 0)
 490                        goto err_out;
 491                err = -EINVAL;
 492                kind = tb[TCA_ACT_KIND];
 493                if (kind == NULL)
 494                        goto err_out;
 495                if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
 496                        goto err_out;
 497        } else {
 498                err = -EINVAL;
 499                if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
 500                        goto err_out;
 501        }
 502
 503        a_o = tc_lookup_action_n(act_name);
 504        if (a_o == NULL) {
 505#ifdef CONFIG_MODULES
 506                rtnl_unlock();
 507                request_module("act_%s", act_name);
 508                rtnl_lock();
 509
 510                a_o = tc_lookup_action_n(act_name);
 511
 512                /* We dropped the RTNL semaphore in order to
 513                 * perform the module load.  So, even if we
 514                 * succeeded in loading the module we have to
 515                 * tell the caller to replay the request.  We
 516                 * indicate this using -EAGAIN.
 517                 */
 518                if (a_o != NULL) {
 519                        err = -EAGAIN;
 520                        goto err_mod;
 521                }
 522#endif
 523                err = -ENOENT;
 524                goto err_out;
 525        }
 526
 527        err = -ENOMEM;
 528        a = kzalloc(sizeof(*a), GFP_KERNEL);
 529        if (a == NULL)
 530                goto err_mod;
 531
 532        /* backward compatibility for policer */
 533        if (name == NULL)
 534                err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
 535        else
 536                err = a_o->init(nla, est, a, ovr, bind);
 537        if (err < 0)
 538                goto err_free;
 539
 540        /* module count goes up only when brand new policy is created
 541           if it exists and is only bound to in a_o->init() then
 542           ACT_P_CREATED is not returned (a zero is).
 543        */
 544        if (err != ACT_P_CREATED)
 545                module_put(a_o->owner);
 546        a->ops = a_o;
 547
 548        return a;
 549
 550err_free:
 551        kfree(a);
 552err_mod:
 553        module_put(a_o->owner);
 554err_out:
 555        return ERR_PTR(err);
 556}
 557
 558struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
 559                                  char *name, int ovr, int bind)
 560{
 561        struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
 562        struct tc_action *head = NULL, *act, *act_prev = NULL;
 563        int err;
 564        int i;
 565
 566        err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
 567        if (err < 0)
 568                return ERR_PTR(err);
 569
 570        for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
 571                act = tcf_action_init_1(tb[i], est, name, ovr, bind);
 572                if (IS_ERR(act))
 573                        goto err;
 574                act->order = i;
 575
 576                if (head == NULL)
 577                        head = act;
 578                else
 579                        act_prev->next = act;
 580                act_prev = act;
 581        }
 582        return head;
 583
 584err:
 585        if (head != NULL)
 586                tcf_action_destroy(head, bind);
 587        return act;
 588}
 589
 590int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
 591                          int compat_mode)
 592{
 593        int err = 0;
 594        struct gnet_dump d;
 595        struct tcf_act_hdr *h = a->priv;
 596
 597        if (h == NULL)
 598                goto errout;
 599
 600        /* compat_mode being true specifies a call that is supposed
 601         * to add additional backward compatiblity statistic TLVs.
 602         */
 603        if (compat_mode) {
 604                if (a->type == TCA_OLD_COMPAT)
 605                        err = gnet_stats_start_copy_compat(skb, 0,
 606                                TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d);
 607                else
 608                        return 0;
 609        } else
 610                err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
 611                                            &h->tcf_lock, &d);
 612
 613        if (err < 0)
 614                goto errout;
 615
 616        if (a->ops != NULL && a->ops->get_stats != NULL)
 617                if (a->ops->get_stats(skb, a) < 0)
 618                        goto errout;
 619
 620        if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 ||
 621            gnet_stats_copy_rate_est(&d, &h->tcf_rate_est) < 0 ||
 622            gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0)
 623                goto errout;
 624
 625        if (gnet_stats_finish_copy(&d) < 0)
 626                goto errout;
 627
 628        return 0;
 629
 630errout:
 631        return -1;
 632}
 633
 634static int
 635tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
 636             u16 flags, int event, int bind, int ref)
 637{
 638        struct tcamsg *t;
 639        struct nlmsghdr *nlh;
 640        unsigned char *b = skb_tail_pointer(skb);
 641        struct nlattr *nest;
 642
 643        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
 644
 645        t = NLMSG_DATA(nlh);
 646        t->tca_family = AF_UNSPEC;
 647        t->tca__pad1 = 0;
 648        t->tca__pad2 = 0;
 649
 650        nest = nla_nest_start(skb, TCA_ACT_TAB);
 651        if (nest == NULL)
 652                goto nla_put_failure;
 653
 654        if (tcf_action_dump(skb, a, bind, ref) < 0)
 655                goto nla_put_failure;
 656
 657        nla_nest_end(skb, nest);
 658
 659        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 660        return skb->len;
 661
 662nla_put_failure:
 663nlmsg_failure:
 664        nlmsg_trim(skb, b);
 665        return -1;
 666}
 667
 668static int
 669act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
 670{
 671        struct sk_buff *skb;
 672
 673        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 674        if (!skb)
 675                return -ENOBUFS;
 676        if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
 677                kfree_skb(skb);
 678                return -EINVAL;
 679        }
 680
 681        return rtnl_unicast(skb, &init_net, pid);
 682}
 683
 684static struct tc_action *
 685tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 686{
 687        struct nlattr *tb[TCA_ACT_MAX+1];
 688        struct tc_action *a;
 689        int index;
 690        int err;
 691
 692        err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
 693        if (err < 0)
 694                goto err_out;
 695
 696        err = -EINVAL;
 697        if (tb[TCA_ACT_INDEX] == NULL ||
 698            nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
 699                goto err_out;
 700        index = nla_get_u32(tb[TCA_ACT_INDEX]);
 701
 702        err = -ENOMEM;
 703        a = kzalloc(sizeof(struct tc_action), GFP_KERNEL);
 704        if (a == NULL)
 705                goto err_out;
 706
 707        err = -EINVAL;
 708        a->ops = tc_lookup_action(tb[TCA_ACT_KIND]);
 709        if (a->ops == NULL)
 710                goto err_free;
 711        if (a->ops->lookup == NULL)
 712                goto err_mod;
 713        err = -ENOENT;
 714        if (a->ops->lookup(a, index) == 0)
 715                goto err_mod;
 716
 717        module_put(a->ops->owner);
 718        return a;
 719
 720err_mod:
 721        module_put(a->ops->owner);
 722err_free:
 723        kfree(a);
 724err_out:
 725        return ERR_PTR(err);
 726}
 727
 728static void cleanup_a(struct tc_action *act)
 729{
 730        struct tc_action *a;
 731
 732        for (a = act; a; a = act) {
 733                act = a->next;
 734                kfree(a);
 735        }
 736}
 737
 738static struct tc_action *create_a(int i)
 739{
 740        struct tc_action *act;
 741
 742        act = kzalloc(sizeof(*act), GFP_KERNEL);
 743        if (act == NULL) {
 744                printk("create_a: failed to alloc!\n");
 745                return NULL;
 746        }
 747        act->order = i;
 748        return act;
 749}
 750
 751static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 752{
 753        struct sk_buff *skb;
 754        unsigned char *b;
 755        struct nlmsghdr *nlh;
 756        struct tcamsg *t;
 757        struct netlink_callback dcb;
 758        struct nlattr *nest;
 759        struct nlattr *tb[TCA_ACT_MAX+1];
 760        struct nlattr *kind;
 761        struct tc_action *a = create_a(0);
 762        int err = -ENOMEM;
 763
 764        if (a == NULL) {
 765                printk("tca_action_flush: couldnt create tc_action\n");
 766                return err;
 767        }
 768
 769        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 770        if (!skb) {
 771                printk("tca_action_flush: failed skb alloc\n");
 772                kfree(a);
 773                return err;
 774        }
 775
 776        b = skb_tail_pointer(skb);
 777
 778        err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
 779        if (err < 0)
 780                goto err_out;
 781
 782        err = -EINVAL;
 783        kind = tb[TCA_ACT_KIND];
 784        a->ops = tc_lookup_action(kind);
 785        if (a->ops == NULL)
 786                goto err_out;
 787
 788        nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
 789        t = NLMSG_DATA(nlh);
 790        t->tca_family = AF_UNSPEC;
 791        t->tca__pad1 = 0;
 792        t->tca__pad2 = 0;
 793
 794        nest = nla_nest_start(skb, TCA_ACT_TAB);
 795        if (nest == NULL)
 796                goto nla_put_failure;
 797
 798        err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
 799        if (err < 0)
 800                goto nla_put_failure;
 801        if (err == 0)
 802                goto noflush_out;
 803
 804        nla_nest_end(skb, nest);
 805
 806        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 807        nlh->nlmsg_flags |= NLM_F_ROOT;
 808        module_put(a->ops->owner);
 809        kfree(a);
 810        err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
 811        if (err > 0)
 812                return 0;
 813
 814        return err;
 815
 816nla_put_failure:
 817nlmsg_failure:
 818        module_put(a->ops->owner);
 819err_out:
 820noflush_out:
 821        kfree_skb(skb);
 822        kfree(a);
 823        return err;
 824}
 825
 826static int
 827tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
 828{
 829        int i, ret;
 830        struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
 831        struct tc_action *head = NULL, *act, *act_prev = NULL;
 832
 833        ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
 834        if (ret < 0)
 835                return ret;
 836
 837        if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
 838                if (tb[1] != NULL)
 839                        return tca_action_flush(tb[1], n, pid);
 840                else
 841                        return -EINVAL;
 842        }
 843
 844        for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
 845                act = tcf_action_get_1(tb[i], n, pid);
 846                if (IS_ERR(act)) {
 847                        ret = PTR_ERR(act);
 848                        goto err;
 849                }
 850                act->order = i;
 851
 852                if (head == NULL)
 853                        head = act;
 854                else
 855                        act_prev->next = act;
 856                act_prev = act;
 857        }
 858
 859        if (event == RTM_GETACTION)
 860                ret = act_get_notify(pid, n, head, event);
 861        else { /* delete */
 862                struct sk_buff *skb;
 863
 864                skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 865                if (!skb) {
 866                        ret = -ENOBUFS;
 867                        goto err;
 868                }
 869
 870                if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event,
 871                                 0, 1) <= 0) {
 872                        kfree_skb(skb);
 873                        ret = -EINVAL;
 874                        goto err;
 875                }
 876
 877                /* now do the delete */
 878                tcf_action_destroy(head, 0);
 879                ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC,
 880                                     n->nlmsg_flags&NLM_F_ECHO);
 881                if (ret > 0)
 882                        return 0;
 883                return ret;
 884        }
 885err:
 886        cleanup_a(head);
 887        return ret;
 888}
 889
 890static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
 891                          u16 flags)
 892{
 893        struct tcamsg *t;
 894        struct nlmsghdr *nlh;
 895        struct sk_buff *skb;
 896        struct nlattr *nest;
 897        unsigned char *b;
 898        int err = 0;
 899
 900        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 901        if (!skb)
 902                return -ENOBUFS;
 903
 904        b = skb_tail_pointer(skb);
 905
 906        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
 907        t = NLMSG_DATA(nlh);
 908        t->tca_family = AF_UNSPEC;
 909        t->tca__pad1 = 0;
 910        t->tca__pad2 = 0;
 911
 912        nest = nla_nest_start(skb, TCA_ACT_TAB);
 913        if (nest == NULL)
 914                goto nla_put_failure;
 915
 916        if (tcf_action_dump(skb, a, 0, 0) < 0)
 917                goto nla_put_failure;
 918
 919        nla_nest_end(skb, nest);
 920
 921        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 922        NETLINK_CB(skb).dst_group = RTNLGRP_TC;
 923
 924        err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
 925        if (err > 0)
 926                err = 0;
 927        return err;
 928
 929nla_put_failure:
 930nlmsg_failure:
 931        kfree_skb(skb);
 932        return -1;
 933}
 934
 935
 936static int
 937tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr)
 938{
 939        int ret = 0;
 940        struct tc_action *act;
 941        struct tc_action *a;
 942        u32 seq = n->nlmsg_seq;
 943
 944        act = tcf_action_init(nla, NULL, NULL, ovr, 0);
 945        if (act == NULL)
 946                goto done;
 947        if (IS_ERR(act)) {
 948                ret = PTR_ERR(act);
 949                goto done;
 950        }
 951
 952        /* dump then free all the actions after update; inserted policy
 953         * stays intact
 954         * */
 955        ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
 956        for (a = act; a; a = act) {
 957                act = a->next;
 958                kfree(a);
 959        }
 960done:
 961        return ret;
 962}
 963
 964static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 965{
 966        struct net *net = sock_net(skb->sk);
 967        struct nlattr *tca[TCA_ACT_MAX + 1];
 968        u32 pid = skb ? NETLINK_CB(skb).pid : 0;
 969        int ret = 0, ovr = 0;
 970
 971        if (net != &init_net)
 972                return -EINVAL;
 973
 974        ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
 975        if (ret < 0)
 976                return ret;
 977
 978        if (tca[TCA_ACT_TAB] == NULL) {
 979                printk("tc_ctl_action: received NO action attribs\n");
 980                return -EINVAL;
 981        }
 982
 983        /* n->nlmsg_flags&NLM_F_CREATE
 984         * */
 985        switch (n->nlmsg_type) {
 986        case RTM_NEWACTION:
 987                /* we are going to assume all other flags
 988                 * imply create only if it doesnt exist
 989                 * Note that CREATE | EXCL implies that
 990                 * but since we want avoid ambiguity (eg when flags
 991                 * is zero) then just set this
 992                 */
 993                if (n->nlmsg_flags&NLM_F_REPLACE)
 994                        ovr = 1;
 995replay:
 996                ret = tcf_action_add(tca[TCA_ACT_TAB], n, pid, ovr);
 997                if (ret == -EAGAIN)
 998                        goto replay;
 999                break;
1000        case RTM_DELACTION:
1001                ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_DELACTION);
1002                break;
1003        case RTM_GETACTION:
1004                ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_GETACTION);
1005                break;
1006        default:
1007                BUG();
1008        }
1009
1010        return ret;
1011}
1012
1013static struct nlattr *
1014find_dump_kind(const struct nlmsghdr *n)
1015{
1016        struct nlattr *tb1, *tb2[TCA_ACT_MAX+1];
1017        struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1018        struct nlattr *nla[TCAA_MAX + 1];
1019        struct nlattr *kind;
1020
1021        if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, NULL) < 0)
1022                return NULL;
1023        tb1 = nla[TCA_ACT_TAB];
1024        if (tb1 == NULL)
1025                return NULL;
1026
1027        if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1),
1028                      NLMSG_ALIGN(nla_len(tb1)), NULL) < 0)
1029                return NULL;
1030
1031        if (tb[1] == NULL)
1032                return NULL;
1033        if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[1]),
1034                      nla_len(tb[1]), NULL) < 0)
1035                return NULL;
1036        kind = tb2[TCA_ACT_KIND];
1037
1038        return kind;
1039}
1040
1041static int
1042tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1043{
1044        struct net *net = sock_net(skb->sk);
1045        struct nlmsghdr *nlh;
1046        unsigned char *b = skb_tail_pointer(skb);
1047        struct nlattr *nest;
1048        struct tc_action_ops *a_o;
1049        struct tc_action a;
1050        int ret = 0;
1051        struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
1052        struct nlattr *kind = find_dump_kind(cb->nlh);
1053
1054        if (net != &init_net)
1055                return 0;
1056
1057        if (kind == NULL) {
1058                printk("tc_dump_action: action bad kind\n");
1059                return 0;
1060        }
1061
1062        a_o = tc_lookup_action(kind);
1063        if (a_o == NULL) {
1064                return 0;
1065        }
1066
1067        memset(&a, 0, sizeof(struct tc_action));
1068        a.ops = a_o;
1069
1070        if (a_o->walk == NULL) {
1071                printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind);
1072                goto nla_put_failure;
1073        }
1074
1075        nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
1076                        cb->nlh->nlmsg_type, sizeof(*t));
1077        t = NLMSG_DATA(nlh);
1078        t->tca_family = AF_UNSPEC;
1079        t->tca__pad1 = 0;
1080        t->tca__pad2 = 0;
1081
1082        nest = nla_nest_start(skb, TCA_ACT_TAB);
1083        if (nest == NULL)
1084                goto nla_put_failure;
1085
1086        ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
1087        if (ret < 0)
1088                goto nla_put_failure;
1089
1090        if (ret > 0) {
1091                nla_nest_end(skb, nest);
1092                ret = skb->len;
1093        } else
1094                nla_nest_cancel(skb, nest);
1095
1096        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1097        if (NETLINK_CB(cb->skb).pid && ret)
1098                nlh->nlmsg_flags |= NLM_F_MULTI;
1099        module_put(a_o->owner);
1100        return skb->len;
1101
1102nla_put_failure:
1103nlmsg_failure:
1104        module_put(a_o->owner);
1105        nlmsg_trim(skb, b);
1106        return skb->len;
1107}
1108
1109static int __init tc_action_init(void)
1110{
1111        rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL);
1112        rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL);
1113        rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action);
1114
1115        return 0;
1116}
1117
1118subsys_initcall(tc_action_init);
1119