diff options
| -rw-r--r-- | net/sched/act_mirred.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index b812c20b66c6..797479369881 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
| @@ -65,48 +65,53 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est, | |||
| 65 | struct tc_mirred *parm; | 65 | struct tc_mirred *parm; |
| 66 | struct tcf_mirred *m; | 66 | struct tcf_mirred *m; |
| 67 | struct tcf_common *pc; | 67 | struct tcf_common *pc; |
| 68 | struct net_device *dev = NULL; | 68 | struct net_device *dev; |
| 69 | int ret = 0, err; | 69 | int ret, ok_push = 0; |
| 70 | int ok_push = 0; | ||
| 71 | 70 | ||
| 72 | if (nla == NULL) | 71 | if (nla == NULL) |
| 73 | return -EINVAL; | 72 | return -EINVAL; |
| 74 | 73 | ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy); | |
| 75 | err = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy); | 74 | if (ret < 0) |
| 76 | if (err < 0) | 75 | return ret; |
| 77 | return err; | ||
| 78 | |||
| 79 | if (tb[TCA_MIRRED_PARMS] == NULL) | 76 | if (tb[TCA_MIRRED_PARMS] == NULL) |
| 80 | return -EINVAL; | 77 | return -EINVAL; |
| 81 | parm = nla_data(tb[TCA_MIRRED_PARMS]); | 78 | parm = nla_data(tb[TCA_MIRRED_PARMS]); |
| 82 | 79 | switch (parm->eaction) { | |
| 80 | case TCA_EGRESS_MIRROR: | ||
| 81 | case TCA_EGRESS_REDIR: | ||
| 82 | break; | ||
| 83 | default: | ||
| 84 | return -EINVAL; | ||
| 85 | } | ||
| 83 | if (parm->ifindex) { | 86 | if (parm->ifindex) { |
| 84 | dev = __dev_get_by_index(&init_net, parm->ifindex); | 87 | dev = __dev_get_by_index(&init_net, parm->ifindex); |
| 85 | if (dev == NULL) | 88 | if (dev == NULL) |
| 86 | return -ENODEV; | 89 | return -ENODEV; |
| 87 | switch (dev->type) { | 90 | switch (dev->type) { |
| 88 | case ARPHRD_TUNNEL: | 91 | case ARPHRD_TUNNEL: |
| 89 | case ARPHRD_TUNNEL6: | 92 | case ARPHRD_TUNNEL6: |
| 90 | case ARPHRD_SIT: | 93 | case ARPHRD_SIT: |
| 91 | case ARPHRD_IPGRE: | 94 | case ARPHRD_IPGRE: |
| 92 | case ARPHRD_VOID: | 95 | case ARPHRD_VOID: |
| 93 | case ARPHRD_NONE: | 96 | case ARPHRD_NONE: |
| 94 | ok_push = 0; | 97 | ok_push = 0; |
| 95 | break; | 98 | break; |
| 96 | default: | 99 | default: |
| 97 | ok_push = 1; | 100 | ok_push = 1; |
| 98 | break; | 101 | break; |
| 99 | } | 102 | } |
| 103 | } else { | ||
| 104 | dev = NULL; | ||
| 100 | } | 105 | } |
| 101 | 106 | ||
| 102 | pc = tcf_hash_check(parm->index, a, bind, &mirred_hash_info); | 107 | pc = tcf_hash_check(parm->index, a, bind, &mirred_hash_info); |
| 103 | if (!pc) { | 108 | if (!pc) { |
| 104 | if (!parm->ifindex) | 109 | if (dev == NULL) |
| 105 | return -EINVAL; | 110 | return -EINVAL; |
| 106 | pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind, | 111 | pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind, |
| 107 | &mirred_idx_gen, &mirred_hash_info); | 112 | &mirred_idx_gen, &mirred_hash_info); |
| 108 | if (IS_ERR(pc)) | 113 | if (IS_ERR(pc)) |
| 109 | return PTR_ERR(pc); | 114 | return PTR_ERR(pc); |
| 110 | ret = ACT_P_CREATED; | 115 | ret = ACT_P_CREATED; |
| 111 | } else { | 116 | } else { |
| 112 | if (!ovr) { | 117 | if (!ovr) { |
| @@ -119,12 +124,12 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est, | |||
| 119 | spin_lock_bh(&m->tcf_lock); | 124 | spin_lock_bh(&m->tcf_lock); |
| 120 | m->tcf_action = parm->action; | 125 | m->tcf_action = parm->action; |
| 121 | m->tcfm_eaction = parm->eaction; | 126 | m->tcfm_eaction = parm->eaction; |
| 122 | if (parm->ifindex) { | 127 | if (dev != NULL) { |
| 123 | m->tcfm_ifindex = parm->ifindex; | 128 | m->tcfm_ifindex = parm->ifindex; |
| 124 | if (ret != ACT_P_CREATED) | 129 | if (ret != ACT_P_CREATED) |
| 125 | dev_put(m->tcfm_dev); | 130 | dev_put(m->tcfm_dev); |
| 126 | m->tcfm_dev = dev; | ||
| 127 | dev_hold(dev); | 131 | dev_hold(dev); |
| 132 | m->tcfm_dev = dev; | ||
| 128 | m->tcfm_ok_push = ok_push; | 133 | m->tcfm_ok_push = ok_push; |
| 129 | } | 134 | } |
| 130 | spin_unlock_bh(&m->tcf_lock); | 135 | spin_unlock_bh(&m->tcf_lock); |
| @@ -154,13 +159,6 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a, | |||
| 154 | 159 | ||
| 155 | spin_lock(&m->tcf_lock); | 160 | spin_lock(&m->tcf_lock); |
| 156 | m->tcf_tm.lastuse = jiffies; | 161 | m->tcf_tm.lastuse = jiffies; |
| 157 | if (m->tcfm_eaction != TCA_EGRESS_MIRROR && | ||
| 158 | m->tcfm_eaction != TCA_EGRESS_REDIR) { | ||
| 159 | if (net_ratelimit()) | ||
| 160 | printk("tcf_mirred unknown action %d\n", | ||
| 161 | m->tcfm_eaction); | ||
| 162 | goto out; | ||
| 163 | } | ||
| 164 | 162 | ||
| 165 | dev = m->tcfm_dev; | 163 | dev = m->tcfm_dev; |
| 166 | if (!(dev->flags & IFF_UP)) { | 164 | if (!(dev->flags & IFF_UP)) { |
