| .. | .. |
|---|
| 716 | 716 | struct nlattr *est, bool ovr, |
|---|
| 717 | 717 | struct netlink_ext_ack *extack) |
|---|
| 718 | 718 | { |
|---|
| 719 | | - int err; |
|---|
| 719 | + int err, ifindex = -1; |
|---|
| 720 | 720 | |
|---|
| 721 | 721 | err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, true, extack); |
|---|
| 722 | 722 | if (err < 0) |
|---|
| 723 | 723 | return err; |
|---|
| 724 | + |
|---|
| 725 | + if (tb[TCA_U32_INDEV]) { |
|---|
| 726 | + ifindex = tcf_change_indev(net, tb[TCA_U32_INDEV], extack); |
|---|
| 727 | + if (ifindex < 0) |
|---|
| 728 | + return -EINVAL; |
|---|
| 729 | + } |
|---|
| 724 | 730 | |
|---|
| 725 | 731 | if (tb[TCA_U32_LINK]) { |
|---|
| 726 | 732 | u32 handle = nla_get_u32(tb[TCA_U32_LINK]); |
|---|
| .. | .. |
|---|
| 756 | 762 | tcf_bind_filter(tp, &n->res, base); |
|---|
| 757 | 763 | } |
|---|
| 758 | 764 | |
|---|
| 759 | | - if (tb[TCA_U32_INDEV]) { |
|---|
| 760 | | - int ret; |
|---|
| 761 | | - ret = tcf_change_indev(net, tb[TCA_U32_INDEV], extack); |
|---|
| 762 | | - if (ret < 0) |
|---|
| 763 | | - return -EINVAL; |
|---|
| 764 | | - n->ifindex = ret; |
|---|
| 765 | | - } |
|---|
| 765 | + if (ifindex >= 0) |
|---|
| 766 | + n->ifindex = ifindex; |
|---|
| 767 | + |
|---|
| 766 | 768 | return 0; |
|---|
| 767 | 769 | } |
|---|
| 768 | 770 | |
|---|
| .. | .. |
|---|
| 810 | 812 | |
|---|
| 811 | 813 | new->ifindex = n->ifindex; |
|---|
| 812 | 814 | new->fshift = n->fshift; |
|---|
| 813 | | - new->res = n->res; |
|---|
| 814 | 815 | new->flags = n->flags; |
|---|
| 815 | 816 | RCU_INIT_POINTER(new->ht_down, ht); |
|---|
| 816 | 817 | |
|---|
| .. | .. |
|---|
| 997 | 998 | return -EINVAL; |
|---|
| 998 | 999 | } |
|---|
| 999 | 1000 | |
|---|
| 1001 | + /* At this point, we need to derive the new handle that will be used to |
|---|
| 1002 | + * uniquely map the identity of this table match entry. The |
|---|
| 1003 | + * identity of the entry that we need to construct is 32 bits made of: |
|---|
| 1004 | + * htid(12b):bucketid(8b):node/entryid(12b) |
|---|
| 1005 | + * |
|---|
| 1006 | + * At this point _we have the table(ht)_ in which we will insert this |
|---|
| 1007 | + * entry. We carry the table's id in variable "htid". |
|---|
| 1008 | + * Note that earlier code picked the ht selection either by a) the user |
|---|
| 1009 | + * providing the htid specified via TCA_U32_HASH attribute or b) when |
|---|
| 1010 | + * no such attribute is passed then the root ht, is default to at ID |
|---|
| 1011 | + * 0x[800][00][000]. Rule: the root table has a single bucket with ID 0. |
|---|
| 1012 | + * If OTOH the user passed us the htid, they may also pass a bucketid of |
|---|
| 1013 | + * choice. 0 is fine. For example a user htid is 0x[600][01][000] it is |
|---|
| 1014 | + * indicating hash bucketid of 1. Rule: the entry/node ID _cannot_ be |
|---|
| 1015 | + * passed via the htid, so even if it was non-zero it will be ignored. |
|---|
| 1016 | + * |
|---|
| 1017 | + * We may also have a handle, if the user passed one. The handle also |
|---|
| 1018 | + * carries the same addressing of htid(12b):bucketid(8b):node/entryid(12b). |
|---|
| 1019 | + * Rule: the bucketid on the handle is ignored even if one was passed; |
|---|
| 1020 | + * rather the value on "htid" is always assumed to be the bucketid. |
|---|
| 1021 | + */ |
|---|
| 1000 | 1022 | if (handle) { |
|---|
| 1023 | + /* Rule: The htid from handle and tableid from htid must match */ |
|---|
| 1001 | 1024 | if (TC_U32_HTID(handle) && TC_U32_HTID(handle ^ htid)) { |
|---|
| 1002 | 1025 | NL_SET_ERR_MSG_MOD(extack, "Handle specified hash table address mismatch"); |
|---|
| 1003 | 1026 | return -EINVAL; |
|---|
| 1004 | 1027 | } |
|---|
| 1005 | | - handle = htid | TC_U32_NODE(handle); |
|---|
| 1006 | | - err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, handle, |
|---|
| 1007 | | - GFP_KERNEL); |
|---|
| 1008 | | - if (err) |
|---|
| 1009 | | - return err; |
|---|
| 1010 | | - } else |
|---|
| 1028 | + /* Ok, so far we have a valid htid(12b):bucketid(8b) but we |
|---|
| 1029 | + * need to finalize the table entry identification with the last |
|---|
| 1030 | + * part - the node/entryid(12b)). Rule: Nodeid _cannot be 0_ for |
|---|
| 1031 | + * entries. Rule: nodeid of 0 is reserved only for tables(see |
|---|
| 1032 | + * earlier code which processes TC_U32_DIVISOR attribute). |
|---|
| 1033 | + * Rule: The nodeid can only be derived from the handle (and not |
|---|
| 1034 | + * htid). |
|---|
| 1035 | + * Rule: if the handle specified zero for the node id example |
|---|
| 1036 | + * 0x60000000, then pick a new nodeid from the pool of IDs |
|---|
| 1037 | + * this hash table has been allocating from. |
|---|
| 1038 | + * If OTOH it is specified (i.e for example the user passed a |
|---|
| 1039 | + * handle such as 0x60000123), then we use it generate our final |
|---|
| 1040 | + * handle which is used to uniquely identify the match entry. |
|---|
| 1041 | + */ |
|---|
| 1042 | + if (!TC_U32_NODE(handle)) { |
|---|
| 1043 | + handle = gen_new_kid(ht, htid); |
|---|
| 1044 | + } else { |
|---|
| 1045 | + handle = htid | TC_U32_NODE(handle); |
|---|
| 1046 | + err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, |
|---|
| 1047 | + handle, GFP_KERNEL); |
|---|
| 1048 | + if (err) |
|---|
| 1049 | + return err; |
|---|
| 1050 | + } |
|---|
| 1051 | + } else { |
|---|
| 1052 | + /* The user did not give us a handle; lets just generate one |
|---|
| 1053 | + * from the table's pool of nodeids. |
|---|
| 1054 | + */ |
|---|
| 1011 | 1055 | handle = gen_new_kid(ht, htid); |
|---|
| 1056 | + } |
|---|
| 1012 | 1057 | |
|---|
| 1013 | 1058 | if (tb[TCA_U32_SEL] == NULL) { |
|---|
| 1014 | 1059 | NL_SET_ERR_MSG_MOD(extack, "Selector not specified"); |
|---|