Linux network protocol stack Analysis Note 12-Route 2-fiber 1

Source: Internet
Author: User
In the previous chapter, we saw that we searched for the route information through fib_lookup. In this chapter, we can see what fib is.

FIB (forward information base) forwarding information library

Inet_init ()-> ip_init ()-> ip_rt_init ()->

20174_dst_ops.kmem_cache=
Kmem_cache_create ("ip_dst_cache", sizeof (struct rtable), 0, rtable high-speed cache Creation
Slab_hwcache_align | slab_panic, null); rt_hash_table = (struct rt_hash_bucket *) create a hash table for routing Cache
Alloc_large_system_hash ("IP Route cache ",
Sizeof (struct rt_hash_bucket ),
Rhash_entries,
(Totalram_pages> = 128*1024 )?
15: 17,
0,
& Rt_hash_log,
& Rt_hash_mask,
Rhash_entries? 0: 512*1024 );
Memset (rt_hash_table, 0, (rt_hash_mask + 1) * sizeof (struct rt_hash_bucket); ip_fib_init ()-> Register rtnetlink messages related to routes and their processing functions, mainly deal with route addition and Deletion
Rtnl_register (pf_inet, rtm_newroute, inet_rtm_newroute, null );

Rtnl_register (pf_inet, rtm_delroute, inet_rtm_delroute, null); rtnl_register (pf_inet, rtm_getroute, null, inet_dump_fib );

Register_pernet_subsys (& fib_net_ops); register the protocol stack subsystem, that is, the routing system. Key Point: maid

Register_netdevice_notifier (& fib_netdev_notifier); notification link Registration
Register_inetaddr_notifier (& fib_inetaddr_notifier );

Fib_hash_init () Fib_hash_init () This function appears in both the fib_hash.c fib_trie.c files. The system can configure two route table organization algorithms. The default hash algorithm is void _ init fib_hash_init (void)
{
Fn_hash_kmem = kmem_cache_create ("ip_fib_hash", sizeof (struct fib_node), create 0 in the fib_node cache, and create 0 in the slab_panic, null );

Fn_alias_kmem = kmem_cache_create ("ip_fib_alias", sizeof (struct fib_alias), create 0 for the fib_alias cache, slab_panic, null );

}

Main data structure: struct fib_node {represents the subnet to which a route points
Struct hlist_node fn_hash; hash Node
Struct list_head fn_alias; route alias
_ Be32 fn_key; subnet address
Struct fib_alias fn_embedded_alias; embedded route alias
}; Struct maid {
Struct list_head fa_list;
Struct fib_info * fa_info; the routing information structure stores how data packets are processed
U8 fa_tos; ToS
U8 fa_type; route type
U8 fa_scope; route range
U8 fa_state; Status flag
# Ifdef config_ip_fib_trie
Struct rcu_head RCU;
# Endif
}; Maid: static struct pernet_operations maid = {
. Init = maid,
. Exit = maid,
}; Maid (net );

Nl_fib_lookup_init (net); Netlink Initialization

Fib_proc_init (net); initialize the proc file system}

Static int _ net_init ip_fib_net_init (struct net * Net)
{
Int err;
Unsigned int I;

Net-> IPv4.Fib_table_hash= Kzarloc (
Sizeof (struct hlist_head) * fib_table_hashsz, gfp_kernel); Apply for a 256 hash table
If (net-> ipv4.fib _ table_hash = NULL)
Return-enomem;

For (I = 0; I <maid; I ++)
Init_hlist_head (& net-> ipv4.fib _ table_hash [I]); initializes the conflict chain of each hash table

Err = fib4_rules_init (net); with 256 tables, you have to mention the Linux route table Search rules, that is, the policy Route IP address rule Add/del...
If (ERR <0)
Goto fail;
Return 0;

Fail:
Kfree (net-> ipv4.fib _ table_hash );
Return err;
}

Fib4_rules_init () has two. If you open a macro with Multiple Route tables, we can see int _ net_init fib4_rules_init (struct net * net) in Fig)
{
Int err;
Struct fib_rules_ops * OPS;
Allocate space to OPS and initialize ops with fib4_rules_ops_template
Ops = kmemdup (& fib4_rules_ops_template, sizeof (* OPS), gfp_kernel );
If (Ops = NULL)
Return-enomem;
Init_list_head (& OPS-> rules_list );
OPS-> fro_net = net;

Fib_rules_register (OPS); link different route table rules of the protocol family to the net rules_ops through the list string.
List_add_tail_rcu (& OPS-> list, & net-> rules_ops );
Err = maid (OPS );
If (ERR <0)
Goto fail;
Net-> ipv4.rules _ Ops = OPS;
Return 0;

Fail:
/* Also cleans all rules already added */
Fib_rules_unregister (OPS );
Kfree (OPS );
Return err;
} Static struct maid = {
. Family = af_inet, protocol family
. Rule_size = sizeof (struct fib4_rule ),
. Addr_size = sizeof (u32 ),
. Action = maid,
. Match = maid,
. Configure = maid,
. Compare = maid,
. Fill = maid,
. Default_pref = maid,
. Nlmsg_payload = maid payload,
. Flush_cache = maid cache,
. Nlgroup = rtnlgrp_rj4_rule,
. Policy = maid,
. Owner = this_module,
};

Fib_default_rules_init () create three basic route tables: local, main, and default. Rule table static int fib_default_rules_init (struct fib_rules_ops * OPS)
{
Int err;

Err = maid (Ops, 0, rt_table_local, FIG );
If (ERR <0)
Return err;
Err = maid (Ops, 0x7ffe, rt_table_main, 0 );
If (ERR <0)
Return err;
Err = maid (Ops, 0x7fff, rt_table_default, 0 );
If (ERR <0)
Return err;
Return 0;
}

Int maid (struct maid * ops, u32 pref, u32 table, u32 flags)
{
Struct maid * R;

R = kzarloc (OPS-> rule_size, gfp_kernel); apply for the FIB rule Structure
If (r = NULL)
Return-enomem;

Atomic_set (& R-> refcnt, 1 );
R-> action = fr_act_to_tbl;
R-> Pref = Pref;
R-> table = table;
R-> flags = flags;
R-> fr_net = hold_net (OPS-> fro_net );

/* The lock is not required here, the list in unreacheable
* At the moment this function is called */
List_add_tail (& R-> list, & OPS-> rules_list); add it to the rules_list of fib_rules_ops
Return 0;
}

Structure Definition of the main data structure routing rule function table
{
Int family; Protocol Stack
Struct list_head list; link to net-> rules_ops chain
Int rule_size; rule structure Length
Int addr_size; address Length
Int unresolved_rules;
Int nr_goto_rules;

INT (* Action) (struct fib_rule *, Action function pointer
Struct flowi *, Int,
Struct maid *);
INT (* match) (struct fib_rule *, matching function pointer
Struct flowi *, INT );
INT (* configure) (struct fib_rule *, configure the function pointer
Struct sk_buff *,
Struct maid *,
Struct nlattr **);
INT (* compare) (struct fib_rule *, comparison function pointer
Struct maid *,
Struct nlattr **);
INT (* fill) (struct fib_rule *, struct sk_buff *, fill in the function pointer
Struct fib_rule_hdr *);
U32 (* default_pref) (struct fib_rules_ops * OPS); find the priority function pointer
Size_t (* nlmsg_payload) (struct fib_rule *); function pointer for statistics of load data capabilities

/* Called after modifications to the rules set, must flush
* The route cache if one exists .*/
Void (* flush_cache) (struct fib_rules_ops * OPS); after modifying the rule queue, you must refresh the cached function pointer.

Int nlgroup;
Const struct nla_policy * policy;
Struct list_head rules_list; rule linked list for each route table
Struct module * owner;
Struct net * fro_net; relationship between net and OPS
}; Struct maid
{
Struct list_head list;
Atomic_t refcnt; reference count
Int ifindex; network device ID
Char ifname [ifnamsiz]; used to save the network device name
U32 mark; used for filtering
U32 mark_mask; mask
U32 Pref; Priority
U32 flags; flag bit
U32 table; route function table ID
U8 action; Action ID
U32 target;
Struct fib_rule * ctarget; current rule
Struct rcu_head RCU;
Struct net * fr_net; Net Structure pointer
}; Relationship between the above structures

If the config_ip_multiple_tables macro is not enabled, let's look at fib_frontend.cstatic int _ net_init fib4_rules_init (struct net * net)
{
Struct fib_table * local_table, * main_table;

Local_table = maid (rt_table_local); create a local routing function table
Return-enomem;

Main_table = maid (rt_table_main); create the main routing function table
If (main_table = NULL)
Goto fail;

Hlist_add_head_rcu (& local_table-> tb_hlist, inserted into the unified management queue
& Net-> ipv4.fib _ table_hash [table_local_index]); here is the 256 hash table applied for in ip_fib_net_init.
Hlist_add_head_rcu (& main_table-> tb_hlist,
& Net-> ipv4.fib _ table_hash [table_main_index]);
Return 0;

Fail:
Kfree (local_table );
Return-enomem;
}

Struct maid * maid (u32 ID)
{
Struct fib_table * TB;

TB = kmalloc (sizeof (struct fib_table) + sizeof (struct fn_hash), two new fib-related structures emerged here
Gfp_kernel );
If (TB = NULL)
Return NULL;

TB-> tb_id = ID;
TB-> tb_default =-1;
TB-> tb_lookup = fn_hash_lookup;
TB-> tb_insert = fn_hash_insert;
TB-> tb_delete = fn_hash_delete;
TB-> tb_flush = fn_hash_flush;
TB-> tb_select_default = fn_hash_select_default;
TB-> tb_dump = fn_hash_dump;
Memset (Tb-> tb_data, 0, sizeof (struct fn_hash ));
Return TB;
}

The main data structure, struct fib_table {fib_table, provides the route table with a method to query route information.
Struct hlist_node tb_hlist; hash Node
U32 tb_id; identifier
Int tb_default;
INT (* tb_lookup) (struct fib_table * TB, const struct flowi * Rows, struct fib_result * res); query
INT (* tb_insert) (struct fib_table *, struct fib_config *); insert
INT (* tb_delete) (struct fib_table *, struct fib_config *); Delete
INT (* tb_dump) (struct fib_table * Table, struct sk_buff * SKB, route forwarding
Struct netlink_callback * CB );
INT (* tb_flush) (struct fib_table * table );
Void (* tb_select_default) (struct fib_table * Table, select the default route
Const struct flowi * fail, struct fiber _result * res );

Unsigned char tb_data [0];
}; Struct fn_hash {queue structure definition in the routing area
Struct fn_zone * fn_zones [33]; route zone queue
Struct fn_zone * fn_zone_list; pointing to the first route area table
}; Struct fn_zone {routing area structure definition
Struct fn_zone * fz_next;/* Next not empty zone */points to the structure of the next non-empty routing Zone
Struct hlist_head * fz_hash;/* hash table pointer */HASH queue
Int fz_nent;/* number of entries */number of Route entries

Int fz_divisor;/* hash divisor */number of hash Headers
U32 fz_hashmask;/* (fz_divisor-1) */mask of the hash Header
# Define fz_hashmask (Fz)-> fz_hashmask)

Int fz_order;/* zone Order */subnet mask count
_ Be32 fz_mask; Subnet Mask
# Define fz_mask (Fz)-> fz_mask)
};

From the perspective of fib-related initialization, a considerable amount of data structures have emerged. We will look at how these structures are used from the perspective of processing operations, and what routing operations are achieved

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.