ip_input.c:

int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
	IPv6 ѥåȤμ֤ͤϡѥåȤžʤȤ 0

- in6_dev_get(dev)				: dev->ip6_ptr ݥ󥿤 struct inet6_dev *idev Ϥͤ 1 䤹
  - idev = dev->ip6_ptr				: IPv6 specific data of protocol specific pointers
  - read_lock(&addrconf_lock)			: rwlock_t addrconf_lock  ine6 device ݸԤ
  - atomic_inc(atomic_t *)			: (atomic_t)->counter  increment 
  - read_unlock(&addrconf_lock)

- IP6_INC_STATS_BH(idev,field)			: /proc/net/ ξ򹹿롣
  - SNMP_INC_STATS(mib,field)			: (mib)[2*smp_processor_id()+!in_softirq()].field++ (mib = idev->stats.ipv6)
  - SNMP_INC_STATS_BH(mib,field)		: (mib)[2*smp_processor_id()].field++ (mib = ipv6_statistics)

- skb_share_check(skb, GFP_ATOMIC)		: skb  share buffer åơshare ʤ clone ä֤Τ kfree 
						: When being called from interrupt status or with spinlocks held pri must be GFP_ATOMIC
  - skb_shared(skb)				: skb->users ͤ 1 ʳΤȤ true ֤
    - atomic_read(atomic_t *v)			: (v)->counter ֤ͤ

- ((struct inet6_skb_parm *)skb->cb)->iif = dev->ifindex : Store incoming device index.
						: When the packet will be queued, we cannot refer to skb->dev anymore.

- pskb_may_pull(skb, sizeof(struct ipv6hdr))	: len  skb_headlen(skb) ʲ 1 ֤len > skb->len  0 ֤
						: __pskb_pull_tail(skb, len - skb_headlen(skb))  NULL  0 ֤
  - skb_headlen(struct sk_buff *skb)		: skb->len - skb->data_len ֤
  - __pskb_pull_tail(skb, delta)		: ե饰Ȥ skb Ѥδؿ skb->tail ֤

- hdr = skb->nh.ipv6h

- ipv6_addr_type(struct in6_addr *)

- __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr)) : Cut the length of a buffer down by removing data from the tail.

- if (hdr->nexthdr == NEXTHDR_HOP)
  - skb->h.raw = (u8*)(hdr+1)
  - ipv6_parse_hopopts(skb, offsetof(struct ipv6hdr, nexthdr) : 
    - offsetof(TYPE, MEMB)			: ((size_t) &((TYPE *)0)->MEMB) Ѵ롣ipv6_parse Ǥ̵뤵Ƥ롣
    - ((struct inet6_skb_parm*)skb->cb)->hop = sizeof(struct ipv6hdr)
    - ipv6_parse_tlv(tlvprochopopt_lst, skb)	: Parse tlv encoded option header (hop-by-hop or destination)
						: IPV6_TLV_PAD0, IPV6_TLV_PADN, IPV6_TLV_ROUTERALERT, IPV6_TLV_JUMBO б

- in6_dev_put(idev)				: idev->refcnt 1ĸ餷ơ̵ʤ idev 롣

- NF_HOOK(pf, hook, skb, indev, outdev, okfn)	: hooks[pf][hook]  nf_hook_slow() ˰ܤꡢʤ okfn( = ip6_rcv_finish) ˰ܤ롣
  - okfn(skb) => ip6_rcv_finish(skb)
  - nf_hook_slow(pf, hook, skb, indev, outdev, okfn)
    - kfree(sbk)
    - br_read_lock_bh(BR_NETPROTO_LOCK)
    - skb_checksum_help(skb)
    - nf_iterate(&nf_hooks[pf][hook], &skb, hook, indev, outdev, &elem, okfn) : elem->hook(hook, skb, indev, outdev, okfn) ֤ͤ
						: NF_REPEAT ʤ鼡 nf_hook_ops  hooks[pf][hook] ޤǷ֤
						: ҤäΤ̵ NF_ACCEPT ֤롣
    - switch(result of nf_iterate)
						: NF_STOLEN ϥϥɥ뤵ʤ
    - NF_QUEUE: nf_queue(skb, elem, pf, hook, indev, outdev, okfn)
	queue_handler[pf].outfn  NULL ʤ kfree(skb)
	info = kmalloc(sizeof(*info), GFP_ATOMIC)  NULL ʤ kfree(skb)
	info = (struct nf_info){(struct nf_hook_ops *)elem, pf, hook, indev, outdev, okfn}
	queue_handler[pf].outfn(skb, info, queue_handler[pf].data)  < 0  kfree({info,skb})
      - net_ratelimit()				: printk() ȯ 5sec ޻ߤؿ( DoS )
      - dev_hold(struct net_device *dev)	: dev->refcnt  1 䤹
        - atomic_inc(atomic_t *)
      - dev_put(struct net_device *dev)		: dev->refcnt  1 餷ơ̵ʤ dev ä
        - atomic_dec_and_test(atomic_t *)	: (atomic_t)->counter  decrement ơ0 ʤ true(= !0)֤
	- netdev_finish_unregister(dev)		: dev ˾ädestructor м¹Ԥ롣
						: self-dectruct(destruct? refer to netdevice.h:line 353)ǥХ kfree 
    - NF_ACCEPT: okfn(skb)
    - NF_DROP: kfree(skb)
    - br_read_unlock_bh(BR_NETPROTO_LOCK)

static inline int ip6_rcv_finish(struct sk_buff *skb)
	skb->dst->input(skb) 롣
- ip6_route_input(skb)				: skb->dst == NULL ΤȤƤӽФ롣
