- 论坛徽章:
- 1
|
回复 #1 snriyt 的帖子
好像有点眉目了,哈哈
ip_forward.c中
int ip_forward(struct sk_buff *skb)
54 {
55 struct iphdr *iph; /* Our header */
56 struct rtable *rt; /* Route we use */
57 struct ip_options * opt = &(IPCB(skb)->opt);
58
59 if (skb_warn_if_lro(skb))
60 goto drop;
61
62 if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
63 goto drop;
----------------------------------------------------------
if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb))
110 ip_rt_send_redirect(skb);
111
112 skb->priority = rt_tos2priority(iph->tos);
113
114 return NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, rt->u.dst.dev,
115 ip_forward_finish);
116
117 sr_failed:
118 /*
119 * Strict routing permits no gatewaying
120 */
121 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);
122 goto drop;
123
124 too_many_hops:
125 /* Tell the sender its packet died... */
126 IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_INHDRERRORS);
127 icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
128 drop:
129 kfree_skb(skb);
130 return NET_RX_DROP;
131 }
132 对不符合的数据包进行丢弃操作,也就是kfree_skb(skb);
规则方面则是由return NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, rt->u.dst.dev, ip_forward_finish)处理
而
219 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
220 NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
221
NF_HOOK_THRESH宏为({;;;;;})的形式,return应当返回的是括号的最后一个值。
#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
208 ({int __ret; \
209 if ((__ret=nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, thresh, 1)) == 1)\此处调用了nf_hook_thresh函数,若返回1,则执行(okfn)(skb),就是ip_forward_finish(skb)函数,
210 __ret = (okfn)(skb); \
211 __ret;})
static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
163 struct sk_buff *skb,
164 struct net_device *indev,
165 struct net_device *outdev,
166 int (*okfn)(struct sk_buff *), int thresh,
167 int cond)
168 {
169 if (!cond)
170 return 1;
171 #ifndef CONFIG_NETFILTER_DEBUG
172 if (list_empty(&nf_hooks[pf][hook]))
173 return 1;
174 #endif
175 return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh);
176 }
int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
159 struct net_device *indev,
160 struct net_device *outdev,
161 int (*okfn)(struct sk_buff *),
162 int hook_thresh)
163 {
164 struct list_head *elem;
165 unsigned int verdict;
166 int ret = 0;
167
168 /* We may already have this, but read-locks nest anyway */
169 rcu_read_lock();
170
171 elem = &nf_hooks[pf][hook];
172 next_hook:
173 verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev,
174 outdev, &elem, okfn, hook_thresh);
175 if (verdict == NF_ACCEPT || verdict == NF_STOP) {////如果规则中的值为NF_ACCEPT或者为NF_STOP则返回1.如果为NF——DROP则丢弃,kfree_skb(skb);
176 ret = 1;
177 } else if (verdict == NF_DROP) {
178 kfree_skb(skb);
179 ret = -EPERM;
180 } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
181 if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
182 verdict >> NF_VERDICT_BITS))
183 goto next_hook;
184 }
185 rcu_read_unlock();
186 return ret;
187 } |
|