what do these 9 network functions actually do?

will fitzgerald (linux_learning@yahoo.co.uk)
Fri, 27 Sep 2002 15:35:53 +0100 (BST)


hi all,

this message is not as long as you think so please
help!!

i was hoping someone could explain what is it exactly
that each of these functions do.
a general over all description will do. i'm just
trying to get my head around the kernel functionality.
i've inserted printk's into a linux router and i'm
just testing some stuff on ip forwarding.
i have supplied the full code to the functions. i'm
using kernel 2.4.14 (old i know!!!!)

skb_bond() in dev.c
net_rx_action() calls it, it returns and then
net_rx_action calls ip_rcv() but what is skb_bond
doing?

/* Reparent skb to master device. This function is
called
* only from net_rx_action under BR_NETPROTO_LOCK. It
is misuse
* of BR_NETPROTO_LOCK, but it is OK for now.
*/
static __inline__ void skb_bond(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;

if (dev->master) {
dev_hold(dev->master);
skb->dev = dev->master;
dev_put(dev);
}
}

****************************************************8
skb_shared() in skbuff.h
ip_rcv() calls it befoe doing a NF_HOOK to call
ip_rcv_finish() again i'm not sure of what it does.

/**
* skb_shared - is the buffer shared
* @skb: buffer to check
*
* Returns true if more than one person has a
reference to this
* buffer.
*/
static inline int skb_shared(struct sk_buff *skb)
{
return (atomic_read(&skb->users) != 1);
}

******************************************************
skb_cloned() in skbuff.h
it seems to be linked to skb_shared() according to the
comments. ip_forwad() calls calling
rt_tos2priority() and skb_cow() and skb_cow calls
skb_cloned().
what is skb cloned used for?

/**
* skb_cloned - is the buffer a clone
* @skb: buffer to check
*
* Returns true if the buffer was generated with
skb_clone() and is
* one of multiple shared copies of the buffer. Cloned
buffers are
* shared data so must not be written to under normal
circumstances.
*/

*****************************************************
static inline int skb_cloned(struct sk_buff *skb)
{
return skb->cloned &&
atomic_read(&skb_shinfo(skb)->dataref) != 1;
}
*****************************************************
rt_tos2priority in route.h
does it give security priority information? even
though i don't have a firewall set on my linux router
(experimenting with networks, hobbie) , it gets called
as i have inserted printk's to test if it gets
called.

static inline char rt_tos2priority(u8 tos)
{
return ip_tos2prio[IPTOS_TOS(tos)>>1];
}

****************************************************
ip_decrease_ttl() in net/ip.h
whats the purpose of this?

/* The function in 2.2 was invalid, producing wrong
result for
* check=0xFEFF. It was noticed by Arthur Skawina
_year_ ago. --ANK(000625) */
static inline
int ip_decrease_ttl(struct iphdr *iph)
{
u32 check = iph->check;
check += __constant_htons(0x0100);
iph->check = check + (check>=0xFFFF);
return --iph->ttl;
}

*****************************************************
ip_send() in net/ip.h
ip_forward_finish() calls this function. what does
this line "skb->len > skb->dst->pmtu" do in order to
make the decision of calling one of two functions?

static inline int ip_send(struct sk_buff *skb)
{
if (skb->len > skb->dst->pmtu)
return ip_fragment(skb, ip_finish_output);
else
return ip_finish_output(skb);
}

*****************************************************
neigh_resolve_output() in neighbour.c
this calls the next two functions below. its called
from ip_finish_output2()
does this lookup fib tables or cahces etc?

int neigh_resolve_output(struct sk_buff *skb)
{
struct dst_entry *dst = skb->dst;
struct neighbour *neigh;

if (!dst || !(neigh = dst->neighbour))
goto discard;

__skb_pull(skb, skb->nh.raw - skb->data);

if (neigh_event_send(neigh, skb) == 0) {
int err;
struct net_device *dev = neigh->dev;
if (dev->hard_header_cache && dst->hh == NULL) {
write_lock_bh(&neigh->lock);
if (dst->hh == NULL)
neigh_hh_init(neigh, dst, dst->ops->protocol);
err = dev->hard_header(skb, dev,
ntohs(skb->protocol), neigh->ha, NULL, skb->len);
write_unlock_bh(&neigh->lock);
} else {
read_lock_bh(&neigh->lock);
err = dev->hard_header(skb, dev,
ntohs(skb->protocol), neigh->ha, NULL, skb->len);
read_unlock_bh(&neigh->lock);
}
if (err >= 0)
return neigh->ops->queue_xmit(skb);
kfree_skb(skb);
return -EINVAL;
}
return 0;

discard:
NEIGH_PRINTK1("neigh_resolve_output: dst=%p
neigh=%p\n", dst, dst ? dst->neighbour : NULL);
kfree_skb(skb);
return -EINVAL;
}

***************************************************
neigh_event_send() in neighbour.h

what does this function check in order to call the
next function: __neigh_event_send(neigh, skb)

static inline int neigh_event_send(struct
neighbour *neigh, struct sk_buff *skb)
{
neigh->used = jiffies;
if
(!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
return __neigh_event_send(neigh, skb);
return 0;
}

******************************************************
__neigh_event_send() in neighbour.c
what exactly is going on here? after the above
function has returned its result this one gets
executed.

int __neigh_event_send(struct neighbour *neigh, struct
sk_buff *skb)
{
write_lock_bh(&neigh->lock);
if
(!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
{
if (!(neigh->nud_state&(NUD_STALE|NUD_INCOMPLETE)))
{
if (neigh->parms->mcast_probes +
neigh->parms->app_probes) {
atomic_set(&neigh->probes,
neigh->parms->ucast_probes);
neigh->nud_state = NUD_INCOMPLETE;
neigh_hold(neigh);
neigh->timer.expires = jiffies +
neigh->parms->retrans_time;
add_timer(&neigh->timer);
write_unlock_bh(&neigh->lock);
neigh->ops->solicit(neigh, skb);
atomic_inc(&neigh->probes);
write_lock_bh(&neigh->lock);
} else {
neigh->nud_state = NUD_FAILED;
write_unlock_bh(&neigh->lock);

if (skb)
kfree_skb(skb);
return 1;
}
}
if (neigh->nud_state == NUD_INCOMPLETE) {
if (skb) {
if (skb_queue_len(&neigh->arp_queue) >=
neigh->parms->queue_len) {
struct sk_buff *buff;
buff = neigh->arp_queue.next;
__skb_unlink(buff, &neigh->arp_queue);
kfree_skb(buff);
}
__skb_queue_tail(&neigh->arp_queue, skb);
}
write_unlock_bh(&neigh->lock);
return 1;
}
if (neigh->nud_state == NUD_STALE) {
NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
neigh_hold(neigh);
neigh->nud_state = NUD_DELAY;
neigh->timer.expires = jiffies +
neigh->parms->delay_probe_time;
add_timer(&neigh->timer);
}
}
write_unlock_bh(&neigh->lock);
return 0;
}

thank you for your time,
regards will.

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/