Longue histoire courte, j'essaye de construire un UDP SKB d'os très nus juste pour obtenir quelque chose sur le fil. Le scénario est le suivant:construire un sk_buff pour le périphérique d'évacuation linux kernel
J'ai un chargement de module noyau qui (entre autres choses) remplace l'emplacement de mémoire de la fonction standard udp_sendmsg dans /net/ipv4/udp.c. De là, je voudrais construire un skb au point où je peux simplement le mettre sur le fil. Normalement, udp_sendmsg fait simplement un peu de comptabilité UDP, tapes sur un en-tête UDP et l'envoie vers la couche IP pour le routage, les en-têtes L3/L2, etc. J'apporte une partie de cette fonctionnalité dans la fonction sendmsg. A ce moment, je suis juste allouons un SKB:
skb = alloc_skb(1500, GFP_KERNEL);
//skb has 1500 bytes of tail room only
skb_reserve(skb, 500);
//now has head and tail but no data space
data = skb_put(skb, 500);
//now we have an skb with 500 head, 500 data sec, 500 tail
Et puis (après une table de routage seteup) Je suis en train d'ajouter un udp_hdr:
struct udphdr *uh;
skb->transport_header = skb_push(skb, sizeof(struct udphdr));
uh = udp_hdr(skb);
uh->source = 5555;
uh->dest = dport;
uh->len = 18;
uh->check = 0;
et un ip_hdr (seulement les bases remplies):
struct iphdr *iph;
skb->network_header = skb_push(skb, sizeof(struct iphdr));
iph = ip_hdr(skb);
iph->version = 4;
iph->ihl = 5;
iph->tos = inet->tos;
iph->tot_len = htons(skb->len);
iph->protocol = IPPROTO_UDP;
iph->saddr = saddr;
iph->daddr = daddr;
skb->dst = dst_clone(&rt->u.dst);
note: Je suis plus de ce genre de choses de this page mais ils utilisent un noyau plus ancien (pré 2.6.24) où le réseau et les en-têtes de transport étaient des syndicats et appelé nh et h respectifs ly. La nouvelle façon consiste à utiliser skb-> transport_header/skb-> network_header et d'utiliser ces fonctions d'aide mais apparemment je fais quelque chose de mal parce que je reçois un noyau oups quand j'essaie d'invoquer le udp_sendmsg
Note: ceci a fonctionné sans Oops et déversé indésirable au fil quand au lieu de:
skb->transport_header = skb_push(skb, sizeof(struct udphdr));
je.
skb_reset_transport_header(skb);
(et équivalent pour network_header Mais après avoir lu le lien ci-dessus et en regardant la source de la fonction de remise à zéro sous linux /sk_buff.h, il n'a pas vu Je voulais faire ce que je voulais.
Veuillez également noter que toute déclaration d'affectation ci-dessus avec (dans ce contexte) des variables non définies est simplement parce que je n'ai pas inclus la fonction entière. Je réalise que cette question pourrait tomber dans un domaine très spécifique, mais des conseils sur l'utilisation correcte de la nouvelle construction de skb seraient grandement utiles. Mon pote google arrive assez sec.
Le Oops Dépisteur:
[<ffffffff813dbf98>] oops_end+0xb9/0xc1 [<ffffffff81030e21>] no_context+0x1f6/0x205 [<ffffffff81030fd3>] __bad_area_nosemaphore+0x1a3/0x1c9 [<ffffffff8101184e>] ? apic_timer_interrupt+0xe/0x20 [<ffffffff8103100c>] bad_area_nosemaphore+0x13/0x15 [<ffffffff813dd30a>] do_page_fault+0x125/0x222 [<ffffffff813db485>] page_fault+0x25/0x30 [<ffffffffa010924f>] ? udp_sendmsg_offload+0x1e3/0x250 [testmodule] [<ffffffffa010922e>] ? udp_sendmsg_offload+0x1c2/0x250 [testmodule] [<ffffffff81390a00>] inet_sendmsg+0x54/0x5d [<ffffffff8132f142>] __sock_sendmsg+0x61/0x6c [<ffffffff8132f8b9>] sock_sendmsg+0xcc/0xe5
S'il vous plaît nous montrer les Oops. – ninjalj
poste édité pour refléter le oups –