*/
static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
{
- __be32 paddr = ((struct rtable*)skb->dst)->rt_gateway;
+ __be32 paddr = skb_rtable(skb)->rt_gateway;
struct ddpehdr *ddp;
struct ipddp_route *rt;
struct atalk_addr *our_addr;
union {
struct dst_entry *dst;
- struct rtable *rtable;
unsigned long _skb_dst;
};
#ifdef CONFIG_XFRM
enum dma_data_direction dir);
#endif
+static inline struct rtable *skb_rtable(const struct sk_buff *skb)
+{
+ return (struct rtable *)skb->_skb_dst;
+}
+
extern void kfree_skb(struct sk_buff *skb);
extern void consume_skb(struct sk_buff *skb);
extern void __kfree_skb(struct sk_buff *skb);
static inline int inet_iif(const struct sk_buff *skb)
{
- return skb->rtable->rt_iif;
+ return skb_rtable(skb)->rt_iif;
}
#endif /* _ROUTE_H */
static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+ struct rtable *rt;
if (nf_bridge->mask & BRNF_PKT_TYPE) {
skb->pkt_type = PACKET_OTHERHOST;
}
nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
- skb->rtable = bridge_parent_rtable(nf_bridge->physindev);
- if (!skb->rtable) {
+ rt = bridge_parent_rtable(nf_bridge->physindev);
+ if (!rt) {
kfree_skb(skb);
return 0;
}
- dst_hold(&skb->rtable->u.dst);
+ dst_hold(&rt->u.dst);
+ skb->dst = &rt->u.dst;
skb->dev = nf_bridge->physindev;
nf_bridge_push_encap_header(skb);
struct net_device *dev = skb->dev;
struct iphdr *iph = ip_hdr(skb);
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+ struct rtable *rt;
int err;
if (nf_bridge->mask & BRNF_PKT_TYPE) {
nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
if (dnat_took_place(skb)) {
if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
- struct rtable *rt;
struct flowi fl = {
.nl_u = {
.ip4_u = {
skb->pkt_type = PACKET_HOST;
}
} else {
- skb->rtable = bridge_parent_rtable(nf_bridge->physindev);
- if (!skb->rtable) {
+ rt = bridge_parent_rtable(nf_bridge->physindev);
+ if (!rt) {
kfree_skb(skb);
return 0;
}
- dst_hold(&skb->rtable->u.dst);
+ dst_hold(&rt->u.dst);
+ skb->dst = &rt->u.dst;
}
skb->dev = nf_bridge->physindev;
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- if (skb->rtable && skb->rtable == bridge_parent_rtable(in)) {
- dst_release(&skb->rtable->u.dst);
- skb->rtable = NULL;
+ struct rtable *rt = skb_rtable(skb);
+
+ if (rt && rt == bridge_parent_rtable(in)) {
+ dst_release(&rt->u.dst);
+ skb->dst = NULL;
}
return NF_ACCEPT;
struct sk_buff *skb)
{
struct rtable *rt;
- struct flowi fl = { .oif = skb->rtable->rt_iif,
+ struct flowi fl = { .oif = skb_rtable(skb)->rt_iif,
.nl_u = { .ip4_u =
{ .daddr = ip_hdr(skb)->saddr,
.saddr = ip_hdr(skb)->daddr,
if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
return;
- if (rxskb->rtable->rt_type != RTN_LOCAL)
+ if (skb_rtable(rxskb)->rt_type != RTN_LOCAL)
return;
dst = dccp_v4_route_skb(net, ctl_sk, rxskb);
struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
/* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
- if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
+ if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
return 0; /* discard, don't send a reset here */
if (dccp_bad_service_code(sk, service)) {
return 1;
}
- paddr = skb->rtable->rt_gateway;
+ paddr = skb_rtable(skb)->rt_gateway;
if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev))
return 0;
if (arp->ar_op == htons(ARPOP_REQUEST) &&
ip_route_input(skb, tip, sip, 0, dev) == 0) {
- rt = skb->rtable;
+ rt = skb_rtable(skb);
addr_type = rt->rt_type;
if (addr_type == RTN_LOCAL) {
static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
{
struct ipcm_cookie ipc;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct net *net = dev_net(rt->u.dst.dev);
struct sock *sk;
struct inet_sock *inet;
struct iphdr *iph;
int room;
struct icmp_bxm icmp_param;
- struct rtable *rt = skb_in->rtable;
+ struct rtable *rt = skb_rtable(skb_in);
struct ipcm_cookie ipc;
__be32 saddr;
u8 tos;
RT_TOS(tos), rt2->u.dst.dev);
dst_release(&rt2->u.dst);
- rt2 = skb_in->rtable;
+ rt2 = skb_rtable(skb_in);
skb_in->dst = odst;
}
static void icmp_address_reply(struct sk_buff *skb)
{
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct net_device *dev = skb->dev;
struct in_device *in_dev;
struct in_ifaddr *ifa;
int icmp_rcv(struct sk_buff *skb)
{
struct icmphdr *icmph;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct net *net = dev_net(rt->u.dst.dev);
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
case IGMPV2_HOST_MEMBERSHIP_REPORT:
case IGMPV3_HOST_MEMBERSHIP_REPORT:
/* Is it our report looped back? */
- if (skb->rtable->fl.iif == 0)
+ if (skb_rtable(skb)->fl.iif == 0)
break;
/* don't rely on MC router hearing unicast reports */
if (skb->pkt_type == PACKET_MULTICAST ||
if (!xfrm4_route_forward(skb))
goto drop;
- rt = skb->rtable;
+ rt = skb_rtable(skb);
if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
goto sr_failed;
#ifdef CONFIG_NET_IPGRE_BROADCAST
if (ipv4_is_multicast(iph->daddr)) {
/* Looped back packet, drop it! */
- if (skb->rtable->fl.iif == 0)
+ if (skb_rtable(skb)->fl.iif == 0)
goto drop;
stats->multicast++;
skb->pkt_type = PACKET_BROADCAST;
}
if (skb->protocol == htons(ETH_P_IP)) {
- rt = skb->rtable;
+ rt = skb_rtable(skb);
if ((dst = rt->rt_gateway) == 0)
goto tx_error_icmp;
}
if (iph->ihl > 5 && ip_rcv_options(skb))
goto drop;
- rt = skb->rtable;
+ rt = skb_rtable(skb);
if (rt->rt_type == RTN_MULTICAST) {
IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST,
skb->len);
sptr = skb_network_header(skb);
dptr = dopt->__data;
- daddr = skb->rtable->rt_spec_dst;
+ daddr = skb_rtable(skb)->rt_spec_dst;
if (sopt->rr) {
optlen = sptr[sopt->rr+1];
struct rtable *rt = NULL;
if (skb != NULL) {
- rt = skb->rtable;
+ rt = skb_rtable(skb);
optptr = (unsigned char *)&(ip_hdr(skb)[1]);
} else
optptr = opt->__data;
{
struct ip_options * opt = &(IPCB(skb)->opt);
unsigned char * optptr;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
unsigned char *raw = skb_network_header(skb);
if (opt->rr_needaddr) {
__be32 nexthop;
struct iphdr *iph = ip_hdr(skb);
unsigned char *optptr = skb_network_header(skb) + opt->srr;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct rtable *rt2;
int err;
}
memcpy(&nexthop, &optptr[srrptr-1], 4);
- rt = skb->rtable;
- skb->rtable = NULL;
+ rt = skb_rtable(skb);
+ skb->dst = NULL;
err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);
- rt2 = skb->rtable;
+ rt2 = skb_rtable(skb);
if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {
ip_rt_put(rt2);
- skb->rtable = rt;
+ skb->dst = &rt->u.dst;
return -EINVAL;
}
ip_rt_put(rt);
__be32 saddr, __be32 daddr, struct ip_options *opt)
{
struct inet_sock *inet = inet_sk(sk);
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct iphdr *iph;
/* Build the IP header. */
int ip_mc_output(struct sk_buff *skb)
{
struct sock *sk = skb->sk;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct net_device *dev = rt->u.dst.dev;
/*
/* Skip all of this if the packet is already routed,
* f.e. by something like SCTP.
*/
- rt = skb->rtable;
+ rt = skb_rtable(skb);
if (rt != NULL)
goto packet_routed;
unsigned int mtu, hlen, left, len, ll_rs, pad;
int offset;
__be16 not_last_frag;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
int err = 0;
dev = rt->u.dst.dev;
} replyopts;
struct ipcm_cookie ipc;
__be32 daddr;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
if (ip_options_echo(&replyopts.opt, skb))
return;
static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
{
struct in_pktinfo info;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
info.ipi_addr.s_addr = ip_hdr(skb)->daddr;
if (rt) {
if (!dst) {
/* NBMA tunnel */
- if ((rt = skb->rtable) == NULL) {
+ if ((rt = skb_rtable(skb)) == NULL) {
stats->tx_fifo_errors++;
goto tx_error;
}
if (net->ipv4.vif_table[vif].dev != skb->dev) {
int true_vifi;
- if (skb->rtable->fl.iif == 0) {
+ if (skb_rtable(skb)->fl.iif == 0) {
/* It is our own packet, looped back.
Very complicated situation...
{
struct mfc_cache *cache;
struct net *net = dev_net(skb->dev);
- int local = skb->rtable->rt_flags&RTCF_LOCAL;
+ int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL;
/* Packet is looped back after forward, it should not be
forwarded second time, but still can be delivered locally.
{
int err;
struct mfc_cache *cache;
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
read_lock(&mrt_lock);
cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst);
return NF_ACCEPT;
mr = par->targinfo;
- rt = skb->rtable;
+ rt = skb_rtable(skb);
newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
if (!newsrc) {
printk("MASQUERADE: %s ate my IP address\n", par->out->name);
const char *rep_buffer,
unsigned int rep_len)
{
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct iphdr *iph;
struct tcphdr *tcph;
int oldlen, datalen;
const char *rep_buffer,
unsigned int rep_len)
{
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct iphdr *iph;
struct udphdr *udph;
int datalen, oldlen;
out: return 0;
}
-static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
+static int rt_intern_hash(unsigned hash, struct rtable *rt,
+ struct rtable **rp, struct sk_buff *skb)
{
struct rtable *rth, **rthp;
unsigned long now;
spin_unlock_bh(rt_hash_lock_addr(hash));
rt_drop(rt);
- *rp = rth;
+ if (rp)
+ *rp = rth;
+ else
+ skb->dst = &rth->u.dst;
return 0;
}
rcu_assign_pointer(rt_hash_table[hash].chain, rt);
spin_unlock_bh(rt_hash_lock_addr(hash));
- *rp = rt;
+ if (rp)
+ *rp = rt;
+ else
+ skb->dst = &rt->u.dst;
return 0;
}
&netevent);
rt_del(hash, rth);
- if (!rt_intern_hash(hash, rt, &rt))
+ if (!rt_intern_hash(hash, rt, &rt, NULL))
ip_rt_put(rt);
goto do_next;
}
void ip_rt_send_redirect(struct sk_buff *skb)
{
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct in_device *in_dev = in_dev_get(rt->u.dst.dev);
if (!in_dev)
static int ip_error(struct sk_buff *skb)
{
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
unsigned long now;
int code;
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
- rt = skb->rtable;
+ rt = skb_rtable(skb);
if (rt)
dst_set_expires(&rt->u.dst, 0);
}
in_dev_put(in_dev);
hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
- return rt_intern_hash(hash, rth, &skb->rtable);
+ return rt_intern_hash(hash, rth, NULL, skb);
e_nobufs:
in_dev_put(in_dev);
/* put it into the cache */
hash = rt_hash(daddr, saddr, fl->iif,
rt_genid(dev_net(rth->u.dst.dev)));
- return rt_intern_hash(hash, rth, &skb->rtable);
+ return rt_intern_hash(hash, rth, NULL, skb);
}
/*
}
rth->rt_type = res.type;
hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
- err = rt_intern_hash(hash, rth, &skb->rtable);
+ err = rt_intern_hash(hash, rth, NULL, skb);
goto done;
no_route:
dst_use(&rth->u.dst, jiffies);
RT_CACHE_STAT_INC(in_hit);
rcu_read_unlock();
- skb->rtable = rth;
+ skb->dst = &rth->u.dst;
return 0;
}
RT_CACHE_STAT_INC(in_hlist_search);
if (err == 0) {
hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
rt_genid(dev_net(dev_out)));
- err = rt_intern_hash(hash, rth, rp);
+ err = rt_intern_hash(hash, rth, rp, NULL);
}
return err;
struct sk_buff *skb, u32 pid, u32 seq, int event,
int nowait, unsigned int flags)
{
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct rtmsg *r;
struct nlmsghdr *nlh;
long expires;
err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
local_bh_enable();
- rt = skb->rtable;
+ rt = skb_rtable(skb);
if (err == 0 && rt->u.dst.error)
err = -rt->u.dst.error;
} else {
if (err)
goto errout_free;
- skb->rtable = rt;
+ skb->dst = &rt->u.dst;
if (rtm->rtm_flags & RTM_F_NOTIFY)
rt->rt_flags |= RTCF_NOTIFY;
if (th->rst)
return;
- if (skb->rtable->rt_type != RTN_LOCAL)
+ if (skb_rtable(skb)->rt_type != RTN_LOCAL)
return;
/* Swap the send and the receive. */
#endif
/* Never answer to SYNs send to broadcast or multicast */
- if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
+ if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
goto drop;
/* TW buckets are converted to open requests without
{
struct nf_conntrack_expect *exp;
struct iphdr *iph = ip_hdr(skb);
- struct rtable *rt = skb->rtable;
+ struct rtable *rt = skb_rtable(skb);
struct in_device *in_dev;
__be32 mask = 0;
META_COLLECTOR(int_rtiif)
{
- if (unlikely(skb->rtable == NULL))
+ if (unlikely(skb_rtable(skb) == NULL))
*err = -1;
else
- dst->value = skb->rtable->fl.iif;
+ dst->value = skb_rtable(skb)->fl.iif;
}
/**************************************************************************
return 0;
/* Is this a broadcast address? */
- if (skb && skb->rtable->rt_flags & RTCF_BROADCAST)
+ if (skb && skb_rtable(skb)->rt_flags & RTCF_BROADCAST)
return 0;
return 1;
/* What interface did this skb arrive on? */
static int sctp_v4_skb_iif(const struct sk_buff *skb)
{
- return skb->rtable->rt_iif;
+ return skb_rtable(skb)->rt_iif;
}
/* Was this packet marked by Explicit Congestion Notification? */
SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n",
__func__, skb, skb->len,
- &skb->rtable->rt_src,
- &skb->rtable->rt_dst);
+ &skb_rtable(skb)->rt_src,
+ &skb_rtable(skb)->rt_dst);
inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
IP_PMTUDISC_DO : IP_PMTUDISC_DONT;