aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2006-08-17 21:14:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 17:55:04 -0400
commit4e902c57417c4c285b98ba2722468d1c3ed83d1b (patch)
tree83251829a4bc9628a3543e5f70e7b11090fe22d9 /net/ipv4/fib_trie.c
parentab32ea5d8a760e7dd4339634e95d7be24ee5b842 (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.c76
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
1127static int 1127static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
1128fn_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);
1266succeeded: 1261succeeded:
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
1551static int 1546static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
1552fn_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);