diff options
author | Thomas Graf <tgraf@suug.ch> | 2006-08-17 21:14:52 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 17:55:04 -0400 |
commit | 4e902c57417c4c285b98ba2722468d1c3ed83d1b (patch) | |
tree | 83251829a4bc9628a3543e5f70e7b11090fe22d9 /net/ipv4/fib_trie.c | |
parent | ab32ea5d8a760e7dd4339634e95d7be24ee5b842 (diff) |
[IPv4]: FIB configuration using struct fib_config
Introduces struct fib_config replacing the ugly struct kern_rta
prone to ordering issues. Avoids creating faked netlink messages
for auto generated routes or requests via ioctl.
A new interface net/nexthop.h is added to help navigate through
nexthop configuration arrays.
A new struct nl_info will be used to carry the necessary netlink
information to be used for notifications later on.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r-- | net/ipv4/fib_trie.c | 76 |
1 files changed, 32 insertions, 44 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 2a580eb2579b..41bef0a88ab6 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1124,17 +1124,14 @@ err: | |||
1124 | return fa_head; | 1124 | return fa_head; |
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | static int | 1127 | static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1128 | fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | ||
1129 | struct nlmsghdr *nlhdr, struct netlink_skb_parms *req) | ||
1130 | { | 1128 | { |
1131 | struct trie *t = (struct trie *) tb->tb_data; | 1129 | struct trie *t = (struct trie *) tb->tb_data; |
1132 | struct fib_alias *fa, *new_fa; | 1130 | struct fib_alias *fa, *new_fa; |
1133 | struct list_head *fa_head = NULL; | 1131 | struct list_head *fa_head = NULL; |
1134 | struct fib_info *fi; | 1132 | struct fib_info *fi; |
1135 | int plen = r->rtm_dst_len; | 1133 | int plen = cfg->fc_dst_len; |
1136 | int type = r->rtm_type; | 1134 | u8 tos = cfg->fc_tos; |
1137 | u8 tos = r->rtm_tos; | ||
1138 | u32 key, mask; | 1135 | u32 key, mask; |
1139 | int err; | 1136 | int err; |
1140 | struct leaf *l; | 1137 | struct leaf *l; |
@@ -1142,11 +1139,7 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1142 | if (plen > 32) | 1139 | if (plen > 32) |
1143 | return -EINVAL; | 1140 | return -EINVAL; |
1144 | 1141 | ||
1145 | key = 0; | 1142 | key = ntohl(cfg->fc_dst); |
1146 | if (rta->rta_dst) | ||
1147 | memcpy(&key, rta->rta_dst, 4); | ||
1148 | |||
1149 | key = ntohl(key); | ||
1150 | 1143 | ||
1151 | pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen); | 1144 | pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen); |
1152 | 1145 | ||
@@ -1157,10 +1150,11 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1157 | 1150 | ||
1158 | key = key & mask; | 1151 | key = key & mask; |
1159 | 1152 | ||
1160 | fi = fib_create_info(r, rta, nlhdr, &err); | 1153 | fi = fib_create_info(cfg); |
1161 | 1154 | if (IS_ERR(fi)) { | |
1162 | if (!fi) | 1155 | err = PTR_ERR(fi); |
1163 | goto err; | 1156 | goto err; |
1157 | } | ||
1164 | 1158 | ||
1165 | l = fib_find_node(t, key); | 1159 | l = fib_find_node(t, key); |
1166 | fa = NULL; | 1160 | fa = NULL; |
@@ -1185,10 +1179,10 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1185 | struct fib_alias *fa_orig; | 1179 | struct fib_alias *fa_orig; |
1186 | 1180 | ||
1187 | err = -EEXIST; | 1181 | err = -EEXIST; |
1188 | if (nlhdr->nlmsg_flags & NLM_F_EXCL) | 1182 | if (cfg->fc_nlflags & NLM_F_EXCL) |
1189 | goto out; | 1183 | goto out; |
1190 | 1184 | ||
1191 | if (nlhdr->nlmsg_flags & NLM_F_REPLACE) { | 1185 | if (cfg->fc_nlflags & NLM_F_REPLACE) { |
1192 | struct fib_info *fi_drop; | 1186 | struct fib_info *fi_drop; |
1193 | u8 state; | 1187 | u8 state; |
1194 | 1188 | ||
@@ -1200,8 +1194,8 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1200 | fi_drop = fa->fa_info; | 1194 | fi_drop = fa->fa_info; |
1201 | new_fa->fa_tos = fa->fa_tos; | 1195 | new_fa->fa_tos = fa->fa_tos; |
1202 | new_fa->fa_info = fi; | 1196 | new_fa->fa_info = fi; |
1203 | new_fa->fa_type = type; | 1197 | new_fa->fa_type = cfg->fc_type; |
1204 | new_fa->fa_scope = r->rtm_scope; | 1198 | new_fa->fa_scope = cfg->fc_scope; |
1205 | state = fa->fa_state; | 1199 | state = fa->fa_state; |
1206 | new_fa->fa_state &= ~FA_S_ACCESSED; | 1200 | new_fa->fa_state &= ~FA_S_ACCESSED; |
1207 | 1201 | ||
@@ -1224,17 +1218,17 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1224 | break; | 1218 | break; |
1225 | if (fa->fa_info->fib_priority != fi->fib_priority) | 1219 | if (fa->fa_info->fib_priority != fi->fib_priority) |
1226 | break; | 1220 | break; |
1227 | if (fa->fa_type == type && | 1221 | if (fa->fa_type == cfg->fc_type && |
1228 | fa->fa_scope == r->rtm_scope && | 1222 | fa->fa_scope == cfg->fc_scope && |
1229 | fa->fa_info == fi) { | 1223 | fa->fa_info == fi) { |
1230 | goto out; | 1224 | goto out; |
1231 | } | 1225 | } |
1232 | } | 1226 | } |
1233 | if (!(nlhdr->nlmsg_flags & NLM_F_APPEND)) | 1227 | if (!(cfg->fc_nlflags & NLM_F_APPEND)) |
1234 | fa = fa_orig; | 1228 | fa = fa_orig; |
1235 | } | 1229 | } |
1236 | err = -ENOENT; | 1230 | err = -ENOENT; |
1237 | if (!(nlhdr->nlmsg_flags & NLM_F_CREATE)) | 1231 | if (!(cfg->fc_nlflags & NLM_F_CREATE)) |
1238 | goto out; | 1232 | goto out; |
1239 | 1233 | ||
1240 | err = -ENOBUFS; | 1234 | err = -ENOBUFS; |
@@ -1244,8 +1238,8 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1244 | 1238 | ||
1245 | new_fa->fa_info = fi; | 1239 | new_fa->fa_info = fi; |
1246 | new_fa->fa_tos = tos; | 1240 | new_fa->fa_tos = tos; |
1247 | new_fa->fa_type = type; | 1241 | new_fa->fa_type = cfg->fc_type; |
1248 | new_fa->fa_scope = r->rtm_scope; | 1242 | new_fa->fa_scope = cfg->fc_scope; |
1249 | new_fa->fa_state = 0; | 1243 | new_fa->fa_state = 0; |
1250 | /* | 1244 | /* |
1251 | * Insert new entry to the list. | 1245 | * Insert new entry to the list. |
@@ -1262,7 +1256,8 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1262 | (fa ? &fa->fa_list : fa_head)); | 1256 | (fa ? &fa->fa_list : fa_head)); |
1263 | 1257 | ||
1264 | rt_cache_flush(-1); | 1258 | rt_cache_flush(-1); |
1265 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req); | 1259 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, |
1260 | &cfg->fc_nlinfo); | ||
1266 | succeeded: | 1261 | succeeded: |
1267 | return 0; | 1262 | return 0; |
1268 | 1263 | ||
@@ -1548,28 +1543,21 @@ static int trie_leaf_remove(struct trie *t, t_key key) | |||
1548 | return 1; | 1543 | return 1; |
1549 | } | 1544 | } |
1550 | 1545 | ||
1551 | static int | 1546 | static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) |
1552 | fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | ||
1553 | struct nlmsghdr *nlhdr, struct netlink_skb_parms *req) | ||
1554 | { | 1547 | { |
1555 | struct trie *t = (struct trie *) tb->tb_data; | 1548 | struct trie *t = (struct trie *) tb->tb_data; |
1556 | u32 key, mask; | 1549 | u32 key, mask; |
1557 | int plen = r->rtm_dst_len; | 1550 | int plen = cfg->fc_dst_len; |
1558 | u8 tos = r->rtm_tos; | 1551 | u8 tos = cfg->fc_tos; |
1559 | struct fib_alias *fa, *fa_to_delete; | 1552 | struct fib_alias *fa, *fa_to_delete; |
1560 | struct list_head *fa_head; | 1553 | struct list_head *fa_head; |
1561 | struct leaf *l; | 1554 | struct leaf *l; |
1562 | struct leaf_info *li; | 1555 | struct leaf_info *li; |
1563 | 1556 | ||
1564 | |||
1565 | if (plen > 32) | 1557 | if (plen > 32) |
1566 | return -EINVAL; | 1558 | return -EINVAL; |
1567 | 1559 | ||
1568 | key = 0; | 1560 | key = ntohl(cfg->fc_dst); |
1569 | if (rta->rta_dst) | ||
1570 | memcpy(&key, rta->rta_dst, 4); | ||
1571 | |||
1572 | key = ntohl(key); | ||
1573 | mask = ntohl(inet_make_mask(plen)); | 1561 | mask = ntohl(inet_make_mask(plen)); |
1574 | 1562 | ||
1575 | if (key & ~mask) | 1563 | if (key & ~mask) |
@@ -1598,13 +1586,12 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1598 | if (fa->fa_tos != tos) | 1586 | if (fa->fa_tos != tos) |
1599 | break; | 1587 | break; |
1600 | 1588 | ||
1601 | if ((!r->rtm_type || | 1589 | if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) && |
1602 | fa->fa_type == r->rtm_type) && | 1590 | (cfg->fc_scope == RT_SCOPE_NOWHERE || |
1603 | (r->rtm_scope == RT_SCOPE_NOWHERE || | 1591 | fa->fa_scope == cfg->fc_scope) && |
1604 | fa->fa_scope == r->rtm_scope) && | 1592 | (!cfg->fc_protocol || |
1605 | (!r->rtm_protocol || | 1593 | fi->fib_protocol == cfg->fc_protocol) && |
1606 | fi->fib_protocol == r->rtm_protocol) && | 1594 | fib_nh_match(cfg, fi) == 0) { |
1607 | fib_nh_match(r, nlhdr, rta, fi) == 0) { | ||
1608 | fa_to_delete = fa; | 1595 | fa_to_delete = fa; |
1609 | break; | 1596 | break; |
1610 | } | 1597 | } |
@@ -1614,7 +1601,8 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1614 | return -ESRCH; | 1601 | return -ESRCH; |
1615 | 1602 | ||
1616 | fa = fa_to_delete; | 1603 | fa = fa_to_delete; |
1617 | rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req); | 1604 | rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, |
1605 | &cfg->fc_nlinfo); | ||
1618 | 1606 | ||
1619 | l = fib_find_node(t, key); | 1607 | l = fib_find_node(t, key); |
1620 | li = find_leaf_info(l, plen); | 1608 | li = find_leaf_info(l, plen); |