Linux2.4.0ip layer forwarding (IP

xiaoxiao2021-03-05  22

Linux2.4.0ip layer forwarding process

Email: getmoon@163.com QQ: 505333 wants to take a moon

Download address: http://linuxsouce.home.sohu.com/download/ipforward.zip

Other documents download: http://linuxsouce.home.sohu.com/download/index.html

/ * About local reception of a packet is local transmission or forwarding, please see the IP layer data flow I painted * /

/ * Forward a packet * /

/ * All options have not been detailed to each option * /

INT ip_forward (struct SK_Buff * SKB)

{

Struct Net_Device * dev2; / * Output Device * /

Struct iphdr * iph; / * urheader * /

Struct RTable * rt; / * route we use * /

Struct ip_options * OPT = & (IPCB (SKB) -> OPT);

UNSIGNED SHORT MTU;

IF (IPCB (SKB) -> OPT.ROUTER_ALERT && IP_CALL_RA_CHAIN ​​(SKB))

Return NET_RX_SUCCESS;

IF (SKB-> PKT_TYPE! = packet_host) / * broadcasted, multicast, mixed mode to be forwarded * /

Goto DROP;

/ *

* According to the RFC, We Must First Decrease the TTL Field. IF

* That Reaches Zero, WE Must Reply An ICMP Control Message Telling

* That the packet's lifetime expression.

* /

IPH = SKB-> NH.IPH;

RT = (struct RTable *) SKB-> DST; / * When this package, SKB-> DST is definitely content * /

IF (iPh-> TTL <= 1) / * TTL value is too small. * /

Goto TOO_MANY_HOPS;

IF (OPT-> IS_STRICTROUTE && RT-> RT_DST! = RT-> RT_GATEWAY) / * If the route is selected from the next station is not a gateway, discard this package * /

Goto SR_FaiLED;

/ *

* Having Picked A Route We Can now send the frame out

* after asseking the firewall permission to do so.

* /

SKB-> Priority = rt_tos2priority (iPh-> TOS); / * Priority * /

DEV2 = RT-> u.dst.dev; / * Send it through this device * /

MTU = RT-> u.dst.pmtu; / * Get this device to connect the network's MTU * /

/ *

* We now generate an icmp host redirect giving the route

* we Calculate.

* /

/ * When the routing is reordered and there is no source routing option, a redirected ICMP package must be generated * /

IF (RT-> RT_FLAGS & RTCF_DOREDIRECT &&! OPT-> SRR)

/ * Re-direction * /

IP_RT_SEND_REDIRECT (SKB);

/ * We are about to mark packet. Copy it! * /

IF ((SKB = SKB_COW (SKB, DEV2-> HARD_HEADER_LEN)) == NULL) / * Reorganize this SKBUFF structure * / return net_rx_drop;

IPH = SKB-> NH.IPH;

OPT = & (IPCB (SKB) -> OPT);

/ * Decrease TTLAFTER SKB COW DONE * /

/ * Reduce TTL, of course, re-calculate the checksum * /

IP_DECREASE_TTL (IPH);

/ *

* We now May Allocate A New Buffer, And Copy The DataGRAM INTO IT.

* If the indeicated interface is up and running, kick it.

* /

IF (SKB-> LEN> MTU & IP_DF)) / * If no slide is set, this package requires fragmentation, send ICMP packages * /

Goto frame_needed;

#ifdef config_ip_route_nat

IF (RT-> RT_FLAGS & RTCF_NAT) {/ * If the NAT conversion is compiled and this route is to be NAT conversion * /

IF (IP_DO_NAT (SKB)) {/ * NAT address conversion processing * /

Kfree_skb (SKB);

Return NET_RX_BAD;

}

}

#ENDIF

/ * Forward detection points, if you do not discard, call ip_forward_finish * /

Return nf_hook (PF_INET, NF_IP_FORWARD, SKB, SKB-> DEV, DEV2,

IP_forward_finish;

FRAG_NEEDED:

/ * Set DF, and it needs to be handled here * /

IP_INC_STATS_BH (IPFragfails);

ICMP_SEND (SKB, ICMP_DEST_UNREACH, ICMP_FRAG_NEED, HTONL (MTU));

Goto DROP;

SR_FaiLED:

/ *

* Strict routing permits no acid

* /

ICMP_SEND (SKB, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);

Goto DROP;

TOO_MANY_HOPS:

/ * Tell the sender its packet died ... * /

ICMP_SEND (SKB, ICMP_TIME_EXCEED, ICMP_EXC_TTL, 0);

Drop:

Kfree_skb (SKB);

Return NET_RX_DROP;

}

Static inline int ip_forward_finish (struct SK_Buff * SKB)

{

Struct ip_options * OPT = & (IPCB (SKB) -> OPT); / * OPT pointing options * /

IP_inc_stats_bh (ipforwdatagrams);

IF (OPT-> OPTLEN == 0) {

#ifdef config_net_faSTroute

Struct RTable * RT = (struct RTable *) SKB-> DST;

IF (RT-> RT_FLAGS & RTCF_FAST &&! NetDev_faster_obstacles) {

STRUCT DST_ENTRY * OLD_DST;

Unsigned h = ((* (u8 *) & rt-> key.dst) ^ (* (u8 *) & rt-> key.src)) & NetDev_faster_hmask; write_lock_irq (& SKB-> dev-> fastpath_lock);

OLD_DST = SKB-> dev-> fastpath [h];

SKB-> dev-> fastpath [h] = dst_clone (& rt-> u.dst);

Write_unlock_irq (& SKB-> dev-> fastpath_lock);

DST_RELEASE (OLD_DST);

}

#ENDIF

Return (IP_SEND (SKB));

}

IP_forward_options (SKB); / * Options for forwarding * /

Return (IP_send (SKB)); / * Send Pack * /

}

Static Inline INT IP_SEND (STRUCT SK_BUFF * SKB)

{

IF (SKB-> LEN> SKB-> DST-> PMTU) / * Judging whether it is required * /

Return ip_fragment (SKB, IP_FINISH_OUTPUT); / * Split Split, IP_FINISH_OUTPUT is the callback function after the slice is finished * /

Else

Return IP_FINISH_OUTPUT (SKB); / * The forwarding process ends, send it out * /

}

__INline__ int ip_finish_output (struct SK_Buff * SKB)

{

Struct Net_Device * dev = SKB-> DST-> DEV;

SKB-> DEV = dev; / * Set the sending device * /

SKB-> protocol = __constant_htons (eth_p_ip); / * Protocol type of the package * /

/ * Before sending, if not discard, call ip_finish_output2 * /

Return nf_hook (PF_INET, NF_IP_POST_ROUTING, SKB, NULL, DEV,

IP_FINISH_OUTPUT2);

}

Static Inline INT IP_FINISH_OUTPUT2 (Struct SK_Buff * SKB)

{

STRUCT DST_ENTRY * DST = SKB-> DST;

Struct hh_cache * hh = dst-> hh;

#ifdef config_netfilter_debug

NF_DEBUG_IP_FINISH_OUTPUT2 (SKB);

#ENDIF / * config_netfilter_debug * /

IF (hh) {/ * has hardware cache structure * /

Read_lock_bh (& HH-> HH_LOCK);

Memcpy (SKB-> DATA - 16, HH-> HH_DATA, 16);

Read_unlock_bh (& HH-> HH_LOCK);

SKB_PUSH (SKB, HH-> HH_LEN);

Return hh-> hh_output (SKB); / * actually calls dev_queue_xmit * /

Else IF (DST-> neighbour)

Return DST-> neighbour-> output (SKB); / * neigh_resolve_output, after the hardware address parsing is over, it is called dev_queue_xmit * /

Printk (kern_debug "khm / n");

Kfree_skb (SKB);

Return-EinVal;

}

转载请注明原文地址:https://www.9cbs.com/read-32622.html

New Post(0)