struct ila_xlat_params {
struct ila_params ip;
- struct ila_identifier identifier;
int ifindex;
- unsigned int dir;
};
struct ila_map {
net_get_random_once(&hashrnd, sizeof(hashrnd));
}
-static inline u32 ila_identifier_hash(struct ila_identifier ident)
+static inline u32 ila_locator_hash(struct ila_locator loc)
{
- u32 *v = (u32 *)ident.v32;
+ u32 *v = (u32 *)loc.v32;
return jhash_2words(v[0], v[1], hashrnd);
}
static inline spinlock_t *ila_get_lock(struct ila_net *ilan,
- struct ila_identifier ident)
+ struct ila_locator loc)
{
- return &ilan->locks[ila_identifier_hash(ident) & ilan->locks_mask];
+ return &ilan->locks[ila_locator_hash(loc) & ilan->locks_mask];
}
static inline int ila_cmp_wildcards(struct ila_map *ila,
- struct ila_addr *iaddr, int ifindex,
- unsigned int dir)
+ struct ila_addr *iaddr, int ifindex)
{
- return (ila->xp.ip.locator_match.v64 &&
- ila->xp.ip.locator_match.v64 != iaddr->loc.v64) ||
- (ila->xp.ifindex && ila->xp.ifindex != ifindex) ||
- !(ila->xp.dir & dir);
+ return (ila->xp.ifindex && ila->xp.ifindex != ifindex);
}
static inline int ila_cmp_params(struct ila_map *ila,
struct ila_xlat_params *xp)
{
- return (ila->xp.ip.locator_match.v64 != xp->ip.locator_match.v64) ||
- (ila->xp.ifindex != xp->ifindex) ||
- (ila->xp.dir != xp->dir);
+ return (ila->xp.ifindex != xp->ifindex);
}
static int ila_cmpfn(struct rhashtable_compare_arg *arg,
{
const struct ila_map *ila = obj;
- return (ila->xp.identifier.v64 != *(__be64 *)arg->key);
+ return (ila->xp.ip.locator_match.v64 != *(__be64 *)arg->key);
}
static inline int ila_order(struct ila_map *ila)
{
int score = 0;
- if (ila->xp.ip.locator_match.v64)
- score += 1 << 0;
-
if (ila->xp.ifindex)
score += 1 << 1;
static const struct rhashtable_params rht_params = {
.nelem_hint = 1024,
.head_offset = offsetof(struct ila_map, node),
- .key_offset = offsetof(struct ila_map, xp.identifier),
+ .key_offset = offsetof(struct ila_map, xp.ip.locator_match),
.key_len = sizeof(u64), /* identifier */
.max_size = 1048576,
.min_size = 256,
};
static struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
- [ILA_ATTR_IDENTIFIER] = { .type = NLA_U64, },
[ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
[ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, },
[ILA_ATTR_IFINDEX] = { .type = NLA_U32, },
- [ILA_ATTR_DIR] = { .type = NLA_U32, },
};
static int parse_nl_config(struct genl_info *info,
{
memset(xp, 0, sizeof(*xp));
- if (info->attrs[ILA_ATTR_IDENTIFIER])
- xp->identifier.v64 = (__force __be64)nla_get_u64(
- info->attrs[ILA_ATTR_IDENTIFIER]);
-
if (info->attrs[ILA_ATTR_LOCATOR])
xp->ip.locator.v64 = (__force __be64)nla_get_u64(
info->attrs[ILA_ATTR_LOCATOR]);
if (info->attrs[ILA_ATTR_IFINDEX])
xp->ifindex = nla_get_s32(info->attrs[ILA_ATTR_IFINDEX]);
- if (info->attrs[ILA_ATTR_DIR])
- xp->dir = nla_get_u32(info->attrs[ILA_ATTR_DIR]);
-
return 0;
}
/* Must be called with rcu readlock */
static inline struct ila_map *ila_lookup_wildcards(struct ila_addr *iaddr,
int ifindex,
- unsigned int dir,
struct ila_net *ilan)
{
struct ila_map *ila;
- ila = rhashtable_lookup_fast(&ilan->rhash_table, &iaddr->ident,
+ ila = rhashtable_lookup_fast(&ilan->rhash_table, &iaddr->loc,
rht_params);
while (ila) {
- if (!ila_cmp_wildcards(ila, iaddr, ifindex, dir))
+ if (!ila_cmp_wildcards(ila, iaddr, ifindex))
return ila;
ila = rcu_access_pointer(ila->next);
}
{
struct ila_map *ila;
- ila = rhashtable_lookup_fast(&ilan->rhash_table, &xp->identifier,
+ ila = rhashtable_lookup_fast(&ilan->rhash_table,
+ &xp->ip.locator_match,
rht_params);
while (ila) {
if (!ila_cmp_params(ila, xp))
}
}
-static int ila_xlat_addr(struct sk_buff *skb, int dir);
+static int ila_xlat_addr(struct sk_buff *skb);
static unsigned int
ila_nf_input(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
- ila_xlat_addr(skb, ILA_DIR_IN);
+ ila_xlat_addr(skb);
return NF_ACCEPT;
}
{
struct ila_net *ilan = net_generic(net, ila_net_id);
struct ila_map *ila, *head;
- spinlock_t *lock = ila_get_lock(ilan, xp->identifier);
+ spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match);
int err = 0, order;
if (!ilan->hooks_registered) {
ila->xp = *xp;
- if (xp->ip.locator_match.v64) {
- /* Precompute checksum difference for translation since we
- * know both the old identifier and the new one.
- */
- ila->xp.ip.csum_diff = compute_csum_diff8(
- (__be32 *)&xp->ip.locator_match,
- (__be32 *)&xp->ip.locator);
- }
+ /* Precompute checksum difference for translation since we
+ * know both the old identifier and the new one.
+ */
+ ila->xp.ip.csum_diff = compute_csum_diff8(
+ (__be32 *)&xp->ip.locator_match,
+ (__be32 *)&xp->ip.locator);
order = ila_order(ila);
spin_lock(lock);
- head = rhashtable_lookup_fast(&ilan->rhash_table, &xp->identifier,
+ head = rhashtable_lookup_fast(&ilan->rhash_table,
+ &xp->ip.locator_match,
rht_params);
if (!head) {
/* New entry for the rhash_table */
{
struct ila_net *ilan = net_generic(net, ila_net_id);
struct ila_map *ila, *head, *prev;
- spinlock_t *lock = ila_get_lock(ilan, xp->identifier);
+ spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match);
int err = -ENOENT;
spin_lock(lock);
head = rhashtable_lookup_fast(&ilan->rhash_table,
- &xp->identifier, rht_params);
+ &xp->ip.locator_match, rht_params);
ila = head;
prev = NULL;
static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg)
{
- if (nla_put_u64_64bit(msg, ILA_ATTR_IDENTIFIER,
- (__force u64)ila->xp.identifier.v64,
- ILA_ATTR_PAD) ||
- nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR,
+ if (nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR,
(__force u64)ila->xp.ip.locator.v64,
ILA_ATTR_PAD) ||
nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR_MATCH,
(__force u64)ila->xp.ip.locator_match.v64,
ILA_ATTR_PAD) ||
- nla_put_s32(msg, ILA_ATTR_IFINDEX, ila->xp.ifindex) ||
- nla_put_u32(msg, ILA_ATTR_DIR, ila->xp.dir))
+ nla_put_s32(msg, ILA_ATTR_IFINDEX, ila->xp.ifindex))
return -1;
return 0;
.size = sizeof(struct ila_net),
};
-static int ila_xlat_addr(struct sk_buff *skb, int dir)
+static int ila_xlat_addr(struct sk_buff *skb)
{
struct ila_map *ila;
struct ipv6hdr *ip6h = ipv6_hdr(skb);
struct net *net = dev_net(skb->dev);
struct ila_net *ilan = net_generic(net, ila_net_id);
struct ila_addr *iaddr = ila_a2i(&ip6h->daddr);
- size_t nhoff;
/* Assumes skb contains a valid IPv6 header that is pulled */
- nhoff = sizeof(struct ipv6hdr);
+ if (!ila_addr_is_ila(iaddr)) {
+ /* Type indicates this is not an ILA address */
+ return 0;
+ }
rcu_read_lock();
- ila = ila_lookup_wildcards(iaddr, skb->dev->ifindex, dir, ilan);
+ ila = ila_lookup_wildcards(iaddr, skb->dev->ifindex, ilan);
if (ila)
ila_update_ipv6_locator(skb, &ila->xp.ip);
return 0;
}
-int ila_xlat_incoming(struct sk_buff *skb)
-{
- return ila_xlat_addr(skb, ILA_DIR_IN);
-}
-EXPORT_SYMBOL(ila_xlat_incoming);
-
-int ila_xlat_outgoing(struct sk_buff *skb)
-{
- return ila_xlat_addr(skb, ILA_DIR_OUT);
-}
-EXPORT_SYMBOL(ila_xlat_outgoing);
-
int ila_xlat_init(void)
{
int ret;