The patch extends the inet_addr_type and inet_dev_addr_type with the
network namespace pointer. That allows to access the different tables
relatively to the network namespace.
The modification of the signature function is reported in all the
callers of the inet_addr_type using the pointer to the well known
init_net.
Acked-by: Benjamin Thery <benjamin.thery@bull.net>
Acked-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
17 files changed:
neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
- neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key);
+ neigh->type = inet_addr_type(&init_net, *(__be32 *) neigh->primary_key);
neigh->nud_state = NUD_NOARP;
neigh->ops = arp_direct_ops;
neigh->output = neigh->ops->queue_xmit;
neigh->nud_state = NUD_NOARP;
neigh->ops = arp_direct_ops;
neigh->output = neigh->ops->queue_xmit;
extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
extern void ip_rt_send_redirect(struct sk_buff *skb);
extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
extern void ip_rt_send_redirect(struct sk_buff *skb);
-extern unsigned inet_addr_type(__be32 addr);
-extern unsigned inet_dev_addr_type(const struct net_device *dev, __be32 addr);
+extern unsigned inet_addr_type(struct net *net, __be32 addr);
+extern unsigned inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr);
extern void ip_rt_multicast_event(struct in_device *);
extern int ip_rt_ioctl(unsigned int cmd, void __user *arg);
extern void ip_rt_get_source(u8 *src, struct rtable *rt);
extern void ip_rt_multicast_event(struct in_device *);
extern int ip_rt_ioctl(unsigned int cmd, void __user *arg);
extern void ip_rt_get_source(u8 *src, struct rtable *rt);
struct neigh_parms *parms;
pr_debug("clip_constructor (neigh %p, entry %p)\n", neigh, entry);
struct neigh_parms *parms;
pr_debug("clip_constructor (neigh %p, entry %p)\n", neigh, entry);
- neigh->type = inet_addr_type(entry->ip);
+ neigh->type = inet_addr_type(&init_net, entry->ip);
if (neigh->type != RTN_UNICAST)
return -EINVAL;
if (neigh->type != RTN_UNICAST)
return -EINVAL;
if (addr_len < sizeof(struct sockaddr_in))
goto out;
if (addr_len < sizeof(struct sockaddr_in))
goto out;
- chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
+ chk_addr_ret = inet_addr_type(&init_net, addr->sin_addr.s_addr);
/* Not specified by any standard per-se, however it breaks too
* many applications when removed. It is unfortunate since
/* Not specified by any standard per-se, however it breaks too
* many applications when removed. It is unfortunate since
struct in_device *in_dev;
struct neigh_parms *parms;
struct in_device *in_dev;
struct neigh_parms *parms;
- neigh->type = inet_addr_type(addr);
+ neigh->type = inet_addr_type(&init_net, addr);
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
default:
case 0: /* By default announce any local IP */
switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
default:
case 0: /* By default announce any local IP */
- if (skb && inet_addr_type(ip_hdr(skb)->saddr) == RTN_LOCAL)
+ if (skb && inet_addr_type(&init_net, ip_hdr(skb)->saddr) == RTN_LOCAL)
saddr = ip_hdr(skb)->saddr;
break;
case 1: /* Restrict announcements of saddr in same subnet */
if (!skb)
break;
saddr = ip_hdr(skb)->saddr;
saddr = ip_hdr(skb)->saddr;
break;
case 1: /* Restrict announcements of saddr in same subnet */
if (!skb)
break;
saddr = ip_hdr(skb)->saddr;
- if (inet_addr_type(saddr) == RTN_LOCAL) {
+ if (inet_addr_type(&init_net, saddr) == RTN_LOCAL) {
/* saddr should be known to target */
if (inet_addr_onlink(in_dev, target, saddr))
break;
/* saddr should be known to target */
if (inet_addr_onlink(in_dev, target, saddr))
break;
paddr = ((struct rtable*)skb->dst)->rt_gateway;
paddr = ((struct rtable*)skb->dst)->rt_gateway;
- if (arp_set_predefined(inet_addr_type(paddr), haddr, paddr, dev))
+ if (arp_set_predefined(inet_addr_type(&init_net, paddr), haddr, paddr, dev))
return 0;
n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
return 0;
n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
/* Special case: IPv4 duplicate address detection packet (RFC2131) */
if (sip == 0) {
if (arp->ar_op == htons(ARPOP_REQUEST) &&
/* Special case: IPv4 duplicate address detection packet (RFC2131) */
if (sip == 0) {
if (arp->ar_op == htons(ARPOP_REQUEST) &&
- inet_addr_type(tip) == RTN_LOCAL &&
+ inet_addr_type(&init_net, tip) == RTN_LOCAL &&
!arp_ignore(in_dev,dev,sip,tip))
arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
dev->dev_addr, sha);
!arp_ignore(in_dev,dev,sip,tip))
arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
dev->dev_addr, sha);
*/
if (n == NULL &&
arp->ar_op == htons(ARPOP_REPLY) &&
*/
if (n == NULL &&
arp->ar_op == htons(ARPOP_REPLY) &&
- inet_addr_type(sip) == RTN_UNICAST)
+ inet_addr_type(&init_net, sip) == RTN_UNICAST)
n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
}
n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
}
* Find address type as if only "dev" was present in the system. If
* on_dev is NULL then all interfaces are taken into consideration.
*/
* Find address type as if only "dev" was present in the system. If
* on_dev is NULL then all interfaces are taken into consideration.
*/
-static inline unsigned __inet_dev_addr_type(const struct net_device *dev,
+static inline unsigned __inet_dev_addr_type(struct net *net,
+ const struct net_device *dev,
__be32 addr)
{
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
__be32 addr)
{
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
- local_table = fib_get_table(&init_net, RT_TABLE_LOCAL);
+ local_table = fib_get_table(net, RT_TABLE_LOCAL);
if (local_table) {
ret = RTN_UNICAST;
if (!local_table->tb_lookup(local_table, &fl, &res)) {
if (local_table) {
ret = RTN_UNICAST;
if (!local_table->tb_lookup(local_table, &fl, &res)) {
-unsigned int inet_addr_type(__be32 addr)
+unsigned int inet_addr_type(struct net *net, __be32 addr)
- return __inet_dev_addr_type(NULL, addr);
+ return __inet_dev_addr_type(net, NULL, addr);
-unsigned int inet_dev_addr_type(const struct net_device *dev, __be32 addr)
+unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
+ __be32 addr)
- return __inet_dev_addr_type(dev, addr);
+ return __inet_dev_addr_type(net, dev, addr);
}
/* Given (packet source, input interface) and optional (dst, oif, tos):
}
/* Given (packet source, input interface) and optional (dst, oif, tos):
if (rt->rt_gateway.sa_family == AF_INET && addr) {
cfg->fc_gw = addr;
if (rt->rt_flags & RTF_GATEWAY &&
if (rt->rt_gateway.sa_family == AF_INET && addr) {
cfg->fc_gw = addr;
if (rt->rt_flags & RTF_GATEWAY &&
- inet_addr_type(addr) == RTN_UNICAST)
+ inet_addr_type(&init_net, addr) == RTN_UNICAST)
cfg->fc_scope = RT_SCOPE_UNIVERSE;
}
cfg->fc_scope = RT_SCOPE_UNIVERSE;
}
fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
/* Check, that this local address finally disappeared. */
fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
/* Check, that this local address finally disappeared. */
- if (inet_addr_type(ifa->ifa_local) != RTN_LOCAL) {
+ if (inet_addr_type(&init_net, ifa->ifa_local) != RTN_LOCAL) {
/* And the last, but not the least thing.
We must flush stray FIB entries.
/* And the last, but not the least thing.
We must flush stray FIB entries.
if (cfg->fc_scope >= RT_SCOPE_LINK)
return -EINVAL;
if (cfg->fc_scope >= RT_SCOPE_LINK)
return -EINVAL;
- if (inet_addr_type(nh->nh_gw) != RTN_UNICAST)
+ if (inet_addr_type(&init_net, nh->nh_gw) != RTN_UNICAST)
return -EINVAL;
if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
return -ENODEV;
return -EINVAL;
if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
return -ENODEV;
if (fi->fib_prefsrc) {
if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
fi->fib_prefsrc != cfg->fc_dst)
if (fi->fib_prefsrc) {
if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
fi->fib_prefsrc != cfg->fc_dst)
- if (inet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
+ if (inet_addr_type(&init_net, fi->fib_prefsrc) != RTN_LOCAL)
if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET))
goto out_unlock;
if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET))
goto out_unlock;
- if (inet_addr_type(fl.fl4_src) == RTN_LOCAL)
+ if (inet_addr_type(&init_net, fl.fl4_src) == RTN_LOCAL)
err = __ip_route_output_key(&rt2, &fl);
else {
struct flowi fl2 = {};
err = __ip_route_output_key(&rt2, &fl);
else {
struct flowi fl2 = {};
*/
if (!sysctl_icmp_ignore_bogus_error_responses &&
*/
if (!sysctl_icmp_ignore_bogus_error_responses &&
- inet_addr_type(iph->daddr) == RTN_BROADCAST) {
+ inet_addr_type(&init_net, iph->daddr) == RTN_BROADCAST) {
if (net_ratelimit())
printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
"type %u, code %u "
if (net_ratelimit())
printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
"type %u, code %u "
__be32 addr;
memcpy(&addr, sptr+soffset-1, 4);
__be32 addr;
memcpy(&addr, sptr+soffset-1, 4);
- if (inet_addr_type(addr) != RTN_LOCAL) {
+ if (inet_addr_type(&init_net, addr) != RTN_LOCAL) {
dopt->ts_needtime = 1;
soffset += 8;
}
dopt->ts_needtime = 1;
soffset += 8;
}
{
__be32 addr;
memcpy(&addr, &optptr[optptr[2]-1], 4);
{
__be32 addr;
memcpy(&addr, &optptr[optptr[2]-1], 4);
- if (inet_addr_type(addr) == RTN_UNICAST)
+ if (inet_addr_type(&init_net, addr) == RTN_UNICAST)
break;
if (skb)
timeptr = (__be32*)&optptr[optptr[2]+3];
break;
if (skb)
timeptr = (__be32*)&optptr[optptr[2]+3];
and the destination is RTN_UNICAST (and not local), then create
a cache_bypass connection entry */
if (sysctl_ip_vs_cache_bypass && svc->fwmark
and the destination is RTN_UNICAST (and not local), then create
a cache_bypass connection entry */
if (sysctl_ip_vs_cache_bypass && svc->fwmark
- && (inet_addr_type(iph->daddr) == RTN_UNICAST)) {
+ && (inet_addr_type(&init_net, iph->daddr) == RTN_UNICAST)) {
int ret, cs;
struct ip_vs_conn *cp;
int ret, cs;
struct ip_vs_conn *cp;
conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
/* check if local node and update the flags */
conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
/* check if local node and update the flags */
- if (inet_addr_type(udest->addr) == RTN_LOCAL) {
+ if (inet_addr_type(&init_net, udest->addr) == RTN_LOCAL) {
conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
| IP_VS_CONN_F_LOCALNODE;
}
conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
| IP_VS_CONN_F_LOCALNODE;
}
- atype = inet_addr_type(udest->addr);
+ atype = inet_addr_type(&init_net, udest->addr);
if (atype != RTN_LOCAL && atype != RTN_UNICAST)
return -EINVAL;
if (atype != RTN_LOCAL && atype != RTN_UNICAST)
return -EINVAL;
unsigned int hh_len;
unsigned int type;
unsigned int hh_len;
unsigned int type;
- type = inet_addr_type(iph->saddr);
+ type = inet_addr_type(&init_net, iph->saddr);
if (addr_type == RTN_UNSPEC)
addr_type = type;
if (addr_type == RTN_UNSPEC)
addr_type = type;
static inline bool match_type(const struct net_device *dev, __be32 addr,
u_int16_t mask)
{
static inline bool match_type(const struct net_device *dev, __be32 addr,
u_int16_t mask)
{
- return !!(mask & (1 << inet_dev_addr_type(dev, addr)));
+ return !!(mask & (1 << inet_dev_addr_type(&init_net, dev, addr)));
if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
goto out;
if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
goto out;
- chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
+ chk_addr_ret = inet_addr_type(&init_net, addr->sin_addr.s_addr);
ret = -EADDRNOTAVAIL;
if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
ret = -EADDRNOTAVAIL;
if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
if (IN_DEV_SEC_REDIRECTS(in_dev) && ip_fib_check_default(new_gw, dev))
goto reject_redirect;
} else {
if (IN_DEV_SEC_REDIRECTS(in_dev) && ip_fib_check_default(new_gw, dev))
goto reject_redirect;
} else {
- if (inet_addr_type(new_gw) != RTN_UNICAST)
+ if (inet_addr_type(&init_net, new_gw) != RTN_UNICAST)
/* Check if the address belongs to the host. */
if (addr_type == IPV6_ADDR_MAPPED) {
v4addr = addr->sin6_addr.s6_addr32[3];
/* Check if the address belongs to the host. */
if (addr_type == IPV6_ADDR_MAPPED) {
v4addr = addr->sin6_addr.s6_addr32[3];
- if (inet_addr_type(v4addr) != RTN_LOCAL) {
+ if (inet_addr_type(&init_net, v4addr) != RTN_LOCAL) {
err = -EADDRNOTAVAIL;
goto out;
}
err = -EADDRNOTAVAIL;
goto out;
}
/* Should this be available for binding? */
static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
{
/* Should this be available for binding? */
static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
{
- int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
+ int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr);
if (addr->v4.sin_addr.s_addr != INADDR_ANY &&
if (addr->v4.sin_addr.s_addr != INADDR_ANY &&