mpls-linux-general Mailing List for MPLS for Linux (Page 106)
Status: Beta
Brought to you by:
jleu
You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(3) |
Dec
(26) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(22) |
Feb
(19) |
Mar
(19) |
Apr
(45) |
May
(52) |
Jun
(101) |
Jul
(79) |
Aug
(24) |
Sep
(43) |
Oct
(54) |
Nov
(71) |
Dec
(53) |
| 2002 |
Jan
(111) |
Feb
(123) |
Mar
(67) |
Apr
(61) |
May
(75) |
Jun
(26) |
Jul
(36) |
Aug
(41) |
Sep
(79) |
Oct
(85) |
Nov
(58) |
Dec
(39) |
| 2003 |
Jan
(26) |
Feb
(61) |
Mar
(80) |
Apr
(56) |
May
(39) |
Jun
(44) |
Jul
(28) |
Aug
(25) |
Sep
(4) |
Oct
(20) |
Nov
(38) |
Dec
(9) |
| 2004 |
Jan
(14) |
Feb
(14) |
Mar
(68) |
Apr
(17) |
May
(45) |
Jun
(42) |
Jul
(41) |
Aug
(23) |
Sep
(46) |
Oct
(89) |
Nov
(55) |
Dec
(33) |
| 2005 |
Jan
(74) |
Feb
(39) |
Mar
(105) |
Apr
(96) |
May
(43) |
Jun
(48) |
Jul
(21) |
Aug
(22) |
Sep
(33) |
Oct
(28) |
Nov
(29) |
Dec
(81) |
| 2006 |
Jan
(37) |
Feb
(32) |
Mar
(147) |
Apr
(37) |
May
(33) |
Jun
(28) |
Jul
(15) |
Aug
(20) |
Sep
(15) |
Oct
(23) |
Nov
(30) |
Dec
(40) |
| 2007 |
Jan
(20) |
Feb
(24) |
Mar
(65) |
Apr
(69) |
May
(41) |
Jun
(53) |
Jul
(39) |
Aug
(76) |
Sep
(53) |
Oct
(43) |
Nov
(26) |
Dec
(24) |
| 2008 |
Jan
(19) |
Feb
(67) |
Mar
(91) |
Apr
(75) |
May
(47) |
Jun
(63) |
Jul
(68) |
Aug
(39) |
Sep
(44) |
Oct
(33) |
Nov
(62) |
Dec
(84) |
| 2009 |
Jan
(14) |
Feb
(39) |
Mar
(55) |
Apr
(63) |
May
(16) |
Jun
(9) |
Jul
(4) |
Aug
(6) |
Sep
(1) |
Oct
(2) |
Nov
(10) |
Dec
(5) |
| 2010 |
Jan
(3) |
Feb
(1) |
Mar
(5) |
Apr
(13) |
May
(4) |
Jun
(5) |
Jul
(2) |
Aug
(8) |
Sep
(6) |
Oct
(1) |
Nov
(2) |
Dec
(2) |
| 2011 |
Jan
(1) |
Feb
(21) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
(6) |
Sep
|
Oct
|
Nov
(2) |
Dec
(6) |
| 2012 |
Jan
(5) |
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(5) |
Aug
(3) |
Sep
(6) |
Oct
|
Nov
|
Dec
|
| 2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
| 2014 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(2) |
Dec
|
|
From: James R. L. <jl...@mi...> - 2003-11-23 16:14:52
|
I can start a 'mpls-linux-devel' mailing list over at SF if you would like. On Sun, Nov 23, 2003 at 10:28:11AM -0500, jamal wrote: > > Not sure if i wanna see another xxtable or netfilter hook in there just > so we can do an LSP ping. I have some ideas, so I dont wanna see the > patch incase it influences me; lets discuss later and if it turns out > netfilter is the better way to go then we will take that path. > Heres what i will do: I am going to write a design description since > there is enough interest. > The discussion belongs to a small list of interested people not netdev. > Anyone willing to create a small mailing list? Make sure you subscribe > DaveM. > This way i can ask for help from people to do coding instead of being > the bottleneck. > > cheers, > jamal > > I am gonna start working on the doc about _NOW_ ; i should have > something late today or early tommorow. > > > On Sun, 2003-11-23 at 08:13, Ramon Casellas wrote: > > On Sat, 22 Nov 2003, Harald Welte wrote: > > > > > now that is interesting. I have a working patch for adding netfilter > > > hooks to the old MPLS stack. If your rewrite doesn't yet have some, > > > I'll gladly add them. > > > > > > I also have a working implementation of the draft-ietf-mpls-lsp-ping-01 > > > based on the netfilter hooks for James Leu's MPLS implementation, btw. > > > > Hi Harald, > > > > Thanks for your anwser. > > > > Some details: > > > > * Jamal and Dave are working on something. As soon as they release the > > code we can get a whole picture of the state of the project. I don't know > > the extent of their rewrite. Maybe jamal and/or Dave can give us an > > overview of their changes. We'll see. > > > > * In the meantime, we are syncing efforts with James. Right know we have a > > patch that applies to test9. It has mostly been a RFC (Rewrite, Format and > > Comment). What I did was: > > - Format the existing code, add comments for each function, start > > documenting, clean up unneeded local variables, conform to C90 > > - Rewrite the procfs implementation to use seq_files (I've tested a > > little and works) > > - Clean up the "tunnel" module. > > it compiles, boots and the entries are created in /proc/net/mpls/* > > > > * Your netfilter and LSP Ping impl. patch would be must welcome. IIRC > > correctly, James was also working on netfilter (I haven't, so I CC'ed him > > here). James, can you give us an overview of that? > > > > * I'm waiting (should come in some days) for James to commit my latest > > changes to the P4 repository. > > > > * CVS and sourceforge releases are out of date. We have two > > possibilities: either you set up a p4 client and wait for James commit, or > > I can provide you with a unified diff for 2.6.0-test9 using my private > > copy. > > > > However, I would be glad to take a look at your patches, even if they > > apply to the old code. > > > > Best regards > > > > > > > > // ------------------------------------------------------------------- > > // Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in... > > // 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas > > > > > > > > -- James R. Leu jl...@mi... |
|
From: jamal <ha...@cy...> - 2003-11-23 15:29:19
|
Not sure if i wanna see another xxtable or netfilter hook in there just so we can do an LSP ping. I have some ideas, so I dont wanna see the patch incase it influences me; lets discuss later and if it turns out netfilter is the better way to go then we will take that path. Heres what i will do: I am going to write a design description since there is enough interest. The discussion belongs to a small list of interested people not netdev. Anyone willing to create a small mailing list? Make sure you subscribe DaveM. This way i can ask for help from people to do coding instead of being the bottleneck. cheers, jamal I am gonna start working on the doc about _NOW_ ; i should have something late today or early tommorow. On Sun, 2003-11-23 at 08:13, Ramon Casellas wrote: > On Sat, 22 Nov 2003, Harald Welte wrote: > > > now that is interesting. I have a working patch for adding netfilter > > hooks to the old MPLS stack. If your rewrite doesn't yet have some, > > I'll gladly add them. > > > > I also have a working implementation of the draft-ietf-mpls-lsp-ping-01 > > based on the netfilter hooks for James Leu's MPLS implementation, btw. > > Hi Harald, > > Thanks for your anwser. > > Some details: > > * Jamal and Dave are working on something. As soon as they release the > code we can get a whole picture of the state of the project. I don't know > the extent of their rewrite. Maybe jamal and/or Dave can give us an > overview of their changes. We'll see. > > * In the meantime, we are syncing efforts with James. Right know we have a > patch that applies to test9. It has mostly been a RFC (Rewrite, Format and > Comment). What I did was: > - Format the existing code, add comments for each function, start > documenting, clean up unneeded local variables, conform to C90 > - Rewrite the procfs implementation to use seq_files (I've tested a > little and works) > - Clean up the "tunnel" module. > it compiles, boots and the entries are created in /proc/net/mpls/* > > * Your netfilter and LSP Ping impl. patch would be must welcome. IIRC > correctly, James was also working on netfilter (I haven't, so I CC'ed him > here). James, can you give us an overview of that? > > * I'm waiting (should come in some days) for James to commit my latest > changes to the P4 repository. > > * CVS and sourceforge releases are out of date. We have two > possibilities: either you set up a p4 client and wait for James commit, or > I can provide you with a unified diff for 2.6.0-test9 using my private > copy. > > However, I would be glad to take a look at your patches, even if they > apply to the old code. > > Best regards > > > > // ------------------------------------------------------------------- > // Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in... > // 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas > > > > |
|
From: James R. L. <jl...@mi...> - 2003-11-23 14:21:45
|
change:
ip route add 128.104.18.114/32 lsp 0x2
to include the nexthop IP, such as:
ip route add 128.104.18.114/32 via 192.168.1.1 lsp 0x2
On Sat, Nov 22, 2003 at 08:10:32PM +0900, Rc Y wrote:
> Hi, everyone.
>=20
> I want to run a simple example of utils/README, But I have a error as=20
> following.
>=20
> # ./mplsadm2 -A -O 0
> Key:0x00000002
> Out Segment add: Success
> #./mplsadm2 -O 0x2 -o push:gen:16:set:eth0:ipv4:128.104.18.114
> Out Instr: Success
> #ip route add 128.104.18.114/32 lsp 0x2
> Error: either "to" is duplicate, or "lsp" is a garbage.
>=20
> When I installed mpls-linux-1.172 with linux-2.4.22 to Redhat8.0, I onl=
y=20
> checked "Standard config".
>=20
> Why does Error occur?
>=20
> Thank you.
>=20
> _________________________________________________________________
> =E3=81=82=E3=81=AA=E3=81=9F=E3=81=AEPC=E3=82=92=E5=AE=88=E3=82=8B=E3=81=
=9F=E3=82=81=E3=81=AB=E5=AE=9A=E6=9C=9F=E7=9A=84=E3=81=AA=E3=82=BB=E3=82=AD=
=E3=83=A5=E3=83=AA=E3=83=86=E3=82=A3=E5=AF=BE=E7=AD=96=E3=82=92=E3=80=82=E3=
=83=9E=E3=82=A4=E3=82=AF=E3=83=AD=E3=82=BD=E3=83=95=E3=83=88 =E3=82=BB=E3=
=82=AD=E3=83=A5=E3=83=AA
> =E3=83=86=E3=82=A3=E6=83=85=E5=A0=B1=E3=82=BB=E3=83=B3=E3=82=BF=E3=83=BC=
http://www.microsoft.com/japan/protect/hm.asp=20
>=20
>=20
>=20
> -------------------------------------------------------
> This SF.net email is sponsored by: SF.net Giveback Program.
> Does SourceForge.net help you be more productive? Does it
> help you create better code? SHARE THE LOVE, and help us help
> YOU! Click Here: http://sourceforge.net/donate/
> _______________________________________________
> mpls-linux-general mailing list
> mpl...@li...
> https://lists.sourceforge.net/lists/listinfo/mpls-linux-general
--=20
James R. Leu
jl...@mi...
|
|
From: Ramon C. <cas...@in...> - 2003-11-23 13:14:00
|
On Sat, 22 Nov 2003, Harald Welte wrote:
> now that is interesting. I have a working patch for adding netfilter
> hooks to the old MPLS stack. If your rewrite doesn't yet have some,
> I'll gladly add them.
>
> I also have a working implementation of the draft-ietf-mpls-lsp-ping-01
> based on the netfilter hooks for James Leu's MPLS implementation, btw.
Hi Harald,
Thanks for your anwser.
Some details:
* Jamal and Dave are working on something. As soon as they release the
code we can get a whole picture of the state of the project. I don't know
the extent of their rewrite. Maybe jamal and/or Dave can give us an
overview of their changes. We'll see.
* In the meantime, we are syncing efforts with James. Right know we have a
patch that applies to test9. It has mostly been a RFC (Rewrite, Format and
Comment). What I did was:
- Format the existing code, add comments for each function, start
documenting, clean up unneeded local variables, conform to C90
- Rewrite the procfs implementation to use seq_files (I've tested a
little and works)
- Clean up the "tunnel" module.
it compiles, boots and the entries are created in /proc/net/mpls/*
* Your netfilter and LSP Ping impl. patch would be must welcome. IIRC
correctly, James was also working on netfilter (I haven't, so I CC'ed him
here). James, can you give us an overview of that?
* I'm waiting (should come in some days) for James to commit my latest
changes to the P4 repository.
* CVS and sourceforge releases are out of date. We have two
possibilities: either you set up a p4 client and wait for James commit, or
I can provide you with a unified diff for 2.6.0-test9 using my private
copy.
However, I would be glad to take a look at your patches, even if they
apply to the old code.
Best regards
// -------------------------------------------------------------------
// Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in...
// 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas
|
|
From: Christophe F. <cf...@ut...> - 2003-11-23 09:43:57
|
On Sun, 23 Nov 2003, Rc Y wrote: Hi, > When I installed mpls-linux as following. > > ----------------------------------------------------------- > # cd /usr/src/linux > # patch -p1 < ../mpls-linux-1.172/patches/linux-kernel.diff > # make oldconfig > # make menuconfig > Code maturity level options ---> > [*] Prompt for development and/or incomplete code/drivers > Networking options ---> > [*] Multi Protocol Label Switching - MPLS > > Next, I succeeded kernel compile. And then I did "make" in util folder. > > ------------------------------------------------------------ > > Would you explain how to use the patched version of "ip" tool in addtion to > the above work. This is explained in mpls-linux-1.1/patches/README.iproute2 : download the sources of the iproute2 package, and apply the patch, which is in file mpls-linux-1.1/patches/iproute2-mpls.diff Hope this helps, -- Christophe Fillot (cf...@ut...) | Universite de Technologie de Compiegne Tel: (+33) 03.44.23.79.02 | Service Informatique - Equipe Reseaux GSM: (+33) 06.70.50.24.55 | Centre de Recherche de Royallieu Fax: (+33) 03.44.23.46.77 | http://www.utc.fr |
|
From: Rc Y <t_t...@ho...> - 2003-11-23 06:05:08
|
Hi.
Thank you for sending back quickly.
I don't understand "the patched version of "ip" tool " well.
When I installed mpls-linux as following.
-----------------------------------------------------------
# cd /usr/src/linux
# patch -p1 < ../mpls-linux-1.172/patches/linux-kernel.diff
# make oldconfig
# make menuconfig
Code maturity level options --->
[*] Prompt for development and/or incomplete code/drivers
Networking options --->
[*] Multi Protocol Label Switching - MPLS
Next, I succeeded kernel compile. And then I did "make" in util folder.
------------------------------------------------------------
Would you explain how to use the patched version of "ip" tool in addtion to
the above work.
Thank you.
>From: Christophe Fillot <cf...@ut...>
>To: Rc Y <t_t...@ho...>
>CC: mpl...@li...
>Subject: Re: [mpls-linux-general] Error of Simple example
>Date: Sat, 22 Nov 2003 17:01:04 +0100 (CET)
>
>On Sat, 22 Nov 2003, Rc Y wrote:
>
> > #ip route add 128.104.18.114/32 lsp 0x2
> > Error: either "to" is duplicate, or "lsp" is a garbage.
> >
> > When I installed mpls-linux-1.172 with linux-2.4.22 to Redhat8.0, I
only
> > checked "Standard config".
>
>Did you use the patched version of "ip" tool, that supports the
>"lsp" keyword ?
>
>Regards
>
_________________________________________________________________
あなたのPCを守るために定期的なセキュリティ対策を。マイクロソフト セキュリ
ティ情報センター http://www.microsoft.com/japan/protect/hm.asp
|
|
From: Ramon C. <cas...@in...> - 2003-11-22 17:38:40
|
On Sat, 22 Nov 2003, Stefan Winter wrote:
> Hello,
>
> after reading utils/README it is not entirely clear to me how a InSegment DLV
> command behaves. The readme only states it will deliver the packet to _a_
> layer-3 Entity. Now, on devices that support IPv4 and IPv6 this is not
> trivial to decide. Does mpls-linux actually look into the layer 3 header to
Hi Stefan,
Yes it does.
This is part of James' experimental code (for the forthcoming 2.6
releases, but IIRC, 2.4 does something similar). Bear in mind though that
IPv6 support needs more work.
mpls-dlv:
...
switch(skb->protocol) {
...
case __constant_htons(ETH_P_IP):
if(mpr->ttl < skb->nh.iph->ttl) {
skb->ip_summed = CHECKSUM_NONE;
skb->nh.iph->ttl = mpr->ttl;
MPLS_DEBUG(("%s: setting ttl
%d\n",fn_name,mpr->ttl));
ip_send_check(skb->nh.iph);
}
retval = ip_rcv(skb,skb->dev,NULL);
MPLS_DEBUG(("%s: result of sending packet to IPv4
%d\n",fn_name,retval));
break;
#ifdef CONFIG_IPV6
case __constant_htons(ETH_P_IPV6):
if(mpr->ttl < skb->nh.ipv6h->hop_limit) {
skb->ip_summed = CHECKSUM_NONE;
skb->nh.ipv6h->hop_limit = mpr->ttl;
MPLS_DEBUG(("%s: setting ttl
%d\n",fn_name,mpr->ttl));
}
retval = ipv6_rcv(skb,skb->dev,NULL);
MPLS_DEBUG(("%s: result of sending packet to IPv6
%d\n",fn_name,retval));
break;
Regards,
R.
// -------------------------------------------------------------------
// Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in...
// 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas
|
|
From: Stefan W. <ma...@st...> - 2003-11-22 16:08:43
|
Hello, after reading utils/README it is not entirely clear to me how a InSegment DLV command behaves. The readme only states it will deliver the packet to _a_ layer-3 Entity. Now, on devices that support IPv4 and IPv6 this is not trivial to decide. Does mpls-linux actually look into the layer 3 header to find out where to deliver to? According to the LSR-STD-MIB, this should be a property to explicitly set (mplsInSegmentAddrType in mplsInSegmentTable). Is such an explicit setting supported / needed? Greetings, Stefan Winter |
|
From: Christophe F. <cf...@ut...> - 2003-11-22 16:01:49
|
On Sat, 22 Nov 2003, Rc Y wrote: > #ip route add 128.104.18.114/32 lsp 0x2 > Error: either "to" is duplicate, or "lsp" is a garbage. > > When I installed mpls-linux-1.172 with linux-2.4.22 to Redhat8.0, I only > checked "Standard config". Did you use the patched version of "ip" tool, that supports the "lsp" keyword ? Regards |
|
From: Rc Y <t_t...@ho...> - 2003-11-22 11:11:15
|
Hi, everyone. I want to run a simple example of utils/README, But I have a error as following. # ./mplsadm2 -A -O 0 Key:0x00000002 Out Segment add: Success #./mplsadm2 -O 0x2 -o push:gen:16:set:eth0:ipv4:128.104.18.114 Out Instr: Success #ip route add 128.104.18.114/32 lsp 0x2 Error: either "to" is duplicate, or "lsp" is a garbage. When I installed mpls-linux-1.172 with linux-2.4.22 to Redhat8.0, I only checked "Standard config". Why does Error occur? Thank you. _________________________________________________________________ あなたのPCを守るために定期的なセキュリティ対策を。マイクロソフト セキュリ ティ情報センター http://www.microsoft.com/japan/protect/hm.asp |
|
From: Ramon C. <cas...@in...> - 2003-11-20 19:01:20
|
Hi Vincent! Rem: Reply != Reply All :))) Don't worry about it, if have made several mistakes like this one in the past :) I'm answering you by private email. R. On Thu, 20 Nov 2003, Vincent Pinel wrote: > Bonjour, |
|
From: Vincent P. <pi...@ai...> - 2003-11-20 18:36:54
|
Bonjour, Je pensais effacer les sources t=E9l=E9charg=E9es sur le P4 lors de mon pro= jet qui sont sur mon disque dur. J'imagine vu tes mails que les versions dont tu disposes sont plus =E0 jour= s que les miennes et que je peux effacer. N'h=E9site pas =E0 me dire si tu penses que j'ai quelque chose d'utile. J'ai mis tous ce qui me restait dans mon public_html (j'ai tout mis un peu = en vrac): http://www.stud.enst.fr/~pinel/MPLSLinux/ Juste un mot pour te dire que je lis toujours les docs pour installer la GE= NTOO parce que ce n'est pas trivial. Si tu as besoin du CD je te le ram=E8n= e.=20 En fait, je suis en train de lire le Linux Howto sur la s=E9quence de d=E9m= arrage qui aprend =E0 faire tenir Linux sur une disquette, ou encore =E0 fa= ire bouter les partitions primaires en boucle les unes sur les autres (je n= e sais pas si tu vois). Histoire de m'amuser =E0 un peu mieux ma=EEtriser l= e processus de boot et pour =EAtre en mesure de mieux me d=E9panner si je p= lante mon install. J'ai pas tout mon temps pour m'amuser en ce moment par ce que je n'ai toujo= urs pas trouv=E9 de boulot, mais bon ... Bonne chance pour ton boulot sur MPLS Linux (James ne doit pas en croire se= s yeux de se r=E9cup=E9rer tous ces patches en si peu de temps, alors qu'il= doit en g=E9n=E9ral r=E9pondre =E0 des d=E9butants sur la liste ...) J'ai pas tout regard=E9 en d=E9tail parce que =E7a me passe un peu =E0 3 ki= lom=E8tres au dessus de la t=EAte, mais l'id=E9e de d=E9placer /proc/net/mp= ls_* dans /proc/net/mpls/* =E7a semble bien plus propre, ... A+ Vincent |
|
From: Ramon C. <cas...@in...> - 2003-11-20 13:51:43
|
Ups.... I meant this one :)
R.
8<-----------------8<------------8<--------------
/****
* mpls_tunnel_destroy - destroy (via ifreq) a tunnel
* 20031120 RCAS: destroy/ unregister_netdevice was missing. (right?)
* answer to myself: it was in mpls_ioctl...
***/
void mpls_tunnel_destroy(struct ifreq *ifr)
{
struct net_device *dev = NULL;
BUG_ON(!ifr);
dev = mpls_tunnel_get_by_name (ifr->ifr_name);
if (dev) {
/* give back the object. we just want the address*/
mpls_tunnel_put(dev);
rtnl_lock();
unregister_netdevice(dev);
rtnl_unlock();
}
}
8<-----------------8<------------8<--------------
8<-----------------8<------------8<--------------
/****
* mpls_tunnel_put - put (release) a reference to a tunnel.
* @dev: device
**/
void mpls_tunnel_put (struct net_device* dev)
{
if (dev)
dev_put(dev);
}
8<-----------------8<------------8<--------------
|
|
From: Ramon C. <cas...@in...> - 2003-11-20 13:26:09
|
Hi James/all, A first step towards mpls_tunnel modularization: module_init(mpls_tunnel_init_module); module_exit(mpls_tunnel_exit_module); /**** * EXPORTED SYMBOLS **/ EXPORT_SYMBOL(mpls_tunnel_create); EXPORT_SYMBOL(mpls_tunnel_destroy); EXPORT_SYMBOL(mpls_tunnel_get_by_name); EXPORT_SYMBOL(mpls_tunnel_get); EXPORT_SYMBOL(mpls_tunnel_put); __deprecated mpls_tunnel_locate(struct ifreq *ifr,int create) This has not even been compiled :) we are still syncing efforts... Comments welcome. Regards, Ramon PS: James, maybe you should create mpls-linux-devel@... I'm not very comfortable dumping patches and files here :) but we need to expose them! // ------------------------------------------------------------------- // Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in... // 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas 8<--------8<-------------8<--------------8<-------- /***************************************************************************** * MPLS * An implementation of the MPLS (MultiProtocol Label * Switching) Architecture for Linux. * * __THIS_FILE__ * * Management of MPLS tunnels, virtual devices named by default * mpls%d and that can be managed using userspace tools like * ip route, ifconfig, etc. * * Remember, that as per RFC, LSPs are unidirectional. * * Usage: * Creation : mpls_tunnel_create * Destruction : mpls_tunnel_destroy * Add/Rem MOI : ioctl on device * - SIOCMPLSTUNNELADDOUT : Set the MOI to the tunnel * - SIOCMPLSTUNNELDELOUT : remove the MOI from the tunnel * * EXPORT_SYMBOL(mpls_tunnel_create); * EXPORT_SYMBOL(mpls_tunnel_destroy); * EXPORT_SYMBOL(mpls_tunnel_get_by_name); * EXPORT_SYMBOL(mpls_tunnel_get); * EXPORT_SYMBOL(mpls_tunnel_put); * * $Id$ * * Authors: * James Leu <jl...@mi...> * Ramon Casellas <cas...@in...> * * (c) 1999-2003 James Leu <jl...@mi...> * (c) 2003 Ramon Casellas <cas...@in...> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * ChangeLog * v-0.1 20031120 RCAS: [RFC] (Rewrite, Format and Comment :-)) * v-0.2 20031120 RCAS: static & exported symbols *****************************************************************************/ #include <linux/config.h> #include <linux/in.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/skbuff.h> #include <linux/if_arp.h> #include <linux/netdevice.h> #include <net/mpls.h> /** * MODULE Information and attributes * **/ const char* mpls_tunnel_name = "mpls_tunnel"; const char* mpls_tunnel_string = "MultiProtocol Label Switching Tunnel Module"; const char* mpls_tunnel_copyright = "(c) 1999-2003 JLeu -- (c) 2003 RCas"; MODULE_AUTHOR("James Leu <jl...@mi...> -- Ramon Casellas <cas...@in...>"); MODULE_DESCRIPTION("MultiProtocol Label Switching protocol"); MODULE_LICENSE("GPL"); /***** ================ DATA TYPES AND STRUCTURES ===================== struct mpls_tunnel_private { struct mpls_out_info *mtp_moi; // pointer to the MOI. struct net_device *mtp_dev; // pointer to our "mentor device" struct sockaddr mtp_dest; // dest = &ifr->ifr_dstaddr; struct mpls_tunnel_private* next; // this->next in list struct net_device_stats stat; // MIB for this device }; net_device +================+ | name = mpls%d | +================+- - -+ @2L| name = mpls1 | | +=================+- - -+- -.-+ @1L| name = mpls0 | | . | +- - - - - - - - -+- - -+ .- -+ | ... |s_ptr| +- - - - - - - - -+- - -+ |mpls_ptr = NULL | | mpls_tunnel_private +- - - - - - - - -+- - -+ +===========+ | ... |priv*}----@2->|moi | +- - - - - - - - -+- - -+ +===========+ - - + |mpls_tunnel_priv*}----@1->|moi |v=@2L| +-----------------+ / +- - - - - -+ - - + | ... | / |mtp_dev=@1L|. . | +=================+ / +- - - - - -+ - --+ / | . . . |t=@3 | mpls_tunnel_list +- - - - - -+=====+ | next=@2 | +===========+ in fact, we have: kmalloc (sizeof(net_device)+sizeof(mpls_tunnel_private) +=================+ @1L | name = mpls0 | ^ +- - - - - - - - -+ | | ... | | +- - - - - - - - -+ | |mpls_ptr = NULL | | +- - - - - - - - -+ | | ... | | +- - - - - - - - -+ | |mpls_tunnel_priv*|--+ | +- - - - - - - - -+ | | | ... | | | +=================+ | | |moi |<-+ | +- - - - - - - - -+ +--<|mtp_dev=@1L | +- - - - - - - - -+ | . . . | +- - - - - - - - -+ | next=@2 | +=================+ - Any reason why we keep a list of pointers to the priv structs and not a list of the actual netdev addresses? ================ TUNNEL MANAGEMENT VIA ifreq ================================= struct ifreq { union { char ifrn_name[IFNAMSIZ]; ... } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; ... short ifru_flags; int ifru_mtu; char * ifru_data; ... } ifr_ifru; }; **** ================ TUNNEL MANAGEMENT : Creation ================================ **** * MPLS SUBSYSTEM KERNEL CORE * ==================================================== * ifreq | * |1 | * v Qdisc * +-------------------------+ +-------------------------+ +-------+ * | mpls_tunnel_create |-4-->| register_netdevice(lck) |---7->| queues| * |2 dev~kmalloc/setup |<-9-r+-------------------------+<-8-r-+-------+ * |3 dev->init = | | ^ 5b-ntfy REG * | mpls_tunnel_dev_init | | | +----------+ * +-------------------------+<10,11----->|*dev_hold | * | | | +----------+ * | +-----------------+ | | * | |mpls_tunnel_init |<--5-+ | * | +-----------------+-r--6--+ * |12 * v * +-------------------------+ * | mpls_tunnel_link | * +-------------------------+ ================ TUNNEL MANAGEMENT : Destruction ============================= **** * MPLS SUBSYSTEM KERNEL CORE * ==================================================== * ifreq | * |1 | * v 2L open? Qdisc * +-------------------------+ +---------------------------+ +-------+ * | mpls_tunnel_destroy |-2-->| unregister_netdevice(lck) |---5->|dv/shut| * +-------------------------+ +---------------------------+<-6-r-+-------+ * +-----------------+ | ^ | ^ 13(todo) 5b-ntfy * | mpls_tnl_close |<--3-+ | | | | ^ UNREGIS * +-----------------+-r--4--+ | | | | * | | | |15 * +-----------------+ | | | | * | mpls_tnl_uninit |<----7----+ | | | * + |-r--12------+ | | * +-----------------+ | | * |8 ^ \10,11 | | * v |9 +---v | | * +-----------------+ +---------+ | | * | mpls_tnl_unlink | |*dev_put | | | * +-----------------+ +---------+ | | * +-----------------+ | | * | mpls_tnl_destruc|<--- 14 ----------+ | * +-----------------+--------------------+ * free_netdev ? ******************************************************************/ /**** * Single linked list of MPLS tunnels. ***/ struct mpls_tunnel_private* mpls_tunnel_list; /**** * ... and corresponding readers/writers rwlock_t. **/ rwlock_t mpls_tunnel_lock = RW_LOCK_UNLOCKED; // mpls_dev2priv(MPLSDEV) Obtain private MPLS extension for a netdevice // mpls_priv2dev(MPLSPRIV) Obtain mentor netdevice for a given (private) tunnel #define mpls_dev2priv(MPLSDEV) \ ((struct mpls_tunnel_private *)((MPLSDEV)->priv) #define mpls_priv2dev(MPLSPRIV) \ ((struct net_device *)((MPLSPRIV)->ntp_dev) #define mpls_dev2mtp(MPLSDEV) mpls_dev2priv(MPLSDEV) #define mpls_mtp2dev(MPLSDEV) mpls_priv2dev(MPLSDEV) /**** * mpls_tunnel_link - link(add) the netdevice to the tunnel list * @dev: device object to link. * * Adds the netdevice "dev" to the list of allocated mpls%d tunnels. * Locks the mpls_tunnel_list using mpls_tunnel_lock. "dev" is the * new head list. * * Called by mpls_tunnel_create after having created (alloced) the * virtual device, and after having dev_hold(dev) it. ***/ static void mpls_tunnel_link(struct net_device *dev) { BUG_ON(!dev); BUG_ON(!mpls_dev2mtp(dev)); write_lock_bh(&mpls_tunnel_lock); mpls_dev2mtp(dev)->next = mpls_tunnel_list; mpls_tunnel_list = mpls_dev2mtp(dev); write_unlock_bh(&mpls_tunnel_lock); } /**** * mpls_tunnel_unlink - unlink(remove) the netdevice from the tunnel list * @dev: device object to unlink. * * Removes the netdevice "dev" to the list of allocated mpls%d tunnels. * Locks the mpls_tunnel_list using mpls_tunnel_lock. * * "dev" is now outside the list... Does not affect ownership. The caller * is responsible for dev_putting the device. ***/ static void mpls_tunnel_unlink(struct net_device *dev) { BUG_ON(!dev); BUG_ON(!mpls_dev2mtp(dev)); struct mpls_tunnel_private **ptr; write_lock_bh(&mpls_tunnel_lock); for(ptr = &mpls_tunnel_list;*ptr;ptr = &((*ptr)->next)) if(*ptr == mpls_dev2mtp(dev)) (*ptr) = mpls_dev2mtp(dev)->next; break; write_unlock_bh(&mpls_tunnel_lock); } /***** * mpls_tunnel_create -- allocates a "by default" "mpls%d", registers the net_ * device with the core kernel, and at the end adds it to the list of tunnels * by means of mpls_tunnel_link * @ifr: request ***/ struct net_device* mpls_tunnel_create(struct ifreq *ifr) { struct net_device *dev = NULL; /* Pointer to the created device */ BUG_ON(!ifr); /* * This is a hack. we allocate the concat of a net_device plus a * mpls_tunnel_private struct. Uhmm,... */ dev = (struct net_device*) kmalloc(sizeof(struct net_device) + sizeof(struct mpls_tunnel_private), GFP_KERNEL); if (!dev) goto err_kmalloc; memset(dev,0,sizeof(struct net_device) + sizeof(struct mpls_tunnel_private)); /* * User Constructor callback... The rest of callbacks will be set by it. */ dev->init = mpls_tunnel_dev_init; #if LINUX_VERSION_CODE < 0x020575 dev->features |= NETIF_F_DYNALLOC; #endif /* * Get the address of the mpls_tunnel_private "extension", that is, the * address of the "wannabe/what would be" the 2nd element of a * net_device array */ dev->priv = (struct mpls_tunnel_private*)(&dev[1]); /* * Back reference to the netdevice */ mpls_dev2mtp(dev)->mtp_dev = dev; /* * Copy the destination address found the request to the sockaddr * in the private extension */ memcpy(&(mpls_dev2mtp(dev)->mtp_dest),&ifr->ifr_dstaddr,sizeof(struct sockaddr)); /* * Get the name "format"/"pattern" from fr->ifr_name */ strcpy(dev->name,ifr->ifr_name); // 20031120 RCAS: the lock was missing (right?) rtnl_lock(); if (dev_alloc_name(dev, dev->name) < 0) goto err_noname; /* Register newly created net_device */ if(register_netdevice(dev) < 0) goto err_register; rtnl_unlock(); // 20031120 RCAS: the lock was missing (right?) -- end /* * Finally, update the kernel alloc'ed name... */ strcpy(ifr->ifr_name,dev->name); /* * and hold a ref and put it the tunnel list */ dev_hold(dev); mpls_tunnel_link(dev); return dev; err_register: err_noname: rtnl_unlock(); kfree(dev); dev = NULL; err_kmalloc: return dev; } /**** * mpls_tunnel_destroy - destroy (via ifreq) a tunnel * 20031120 RCAS: destroy/ unregister_netdevice was missing. (right?) * answer to myself: it was in mpls_ioctl... ***/ void mpls_tunnel_destroy(struct ifreq *ifr) { rtnl_lock(); unregister_netdevice(dev); rtnl_unlock(); } /**** * mpls_tunnel_get_by_name - get a reference given a tunnel's name * * @name: interface name of the virtual device (tunnel) * * 20031120 RCAS: added a dev_hold call, otherwise it is confusing and we break * semantincs and "common sense". **/ struct net_device* mpls_tunnel_get_by_name (const char* name) { BUG_ON(!name); struct net_device *dev = NULL; struct mpls_tunnel_private *ptr; read_lock(&mpls_tunnel_lock); for(ptr = mpls_tunnel_list; ptr; ptr = ptr->next) { if (!strncmp( mpls_priv2dev(ptr)->name , name , IFNAMSIZ)) { dev = mpls_priv2dev(ptr); break; } } read_unlock(&mpls_tunnel_lock); return dev; } /**** * mpls_tunnel_get - get a reference to a tunnel. * @ifr: ifreq data **/ struct net_device* mpls_tunnel_get (struct ifreq* ifr) { return (mpls_tunnel_get_by_name(ifr->ifr_name)); } /**** * mpls_tunnel_put - put (release) a reference to a tunnel. * @ifr: ifreq data **/ struct net_device* mpls_tunnel_put (struct ifreq* ifr) { struct net_device *dev = NULL; read_lock(&mpls_tunnel_lock); for(ptr = mpls_tunnel_list; ptr; ptr = ptr->next) { if (!strncmp( mpls_priv2dev(ptr)->name , ifr->ifr_name , IFNAMSIZ)) { dev = mpls-priv2dev(ptr); break; } } read_unlock(&mpls_tunnel_lock); if (dev) dev_put(dev) return; } /**** * mpls_tunnel_add_out - Sets the MOI for this virtual device. * @dev: netdevice "mpls%d" * * Sets the MOI for this netdevice according to the ifreq ifr * (given the labelspace and the label) * Calls netif_start_queue on the device * * Returns 0 if ok. * Remarks: ifr->ifr_data is a pointer to a mpls_label struct ***/ static int mpls_tunnel_add_out (struct net_device* dev,struct ifreq *ifr) { const char *fn_name = "mpls_tunnel_add_out"; struct mpls_out_info *moi = NULL; struct mpls_label *plabel = NULL; int retval = -ENXIO; MPLS_DEBUG(("%s: enter\n",fn_name)); plabel = &ifr->ifr_data; moi = mpls_get_moi(mpls_label2key(plabel->ml_index, (struct mpls_label*)&ifr->ifr_data)); if (!moi) { retval = -ESRCH; MPLS_DEBUG(("%s: error getting node in radix tree\n",fn_name)); return retval; } mpls_dev2mtp(dev)->mtp_moi = moi; dev->mtu = moi->moi_mtu; dev->iflink = ml.ml_index; netif_start_queue(dev); MPLS_DEBUG(("%s: exit\n",fn_name)); return 0; } /**** * mpls_tunnel_del_out - Resets the MOI for this virtual device to NULL * @dev: netdevice "mpls%d" * @ifr: ifreq * * Resets the MOI for this netdevice. ifr is not used. * * Calls netif_stop_queue on the device * Returns 0 if ok. ***/ static int mpls_tunnel_del_out (struct net_device* dev,struct ifreq *ifr) { const char *fn_name = "mpls_tunnel_del_out"; MPLS_DEBUG(("%s: enter\n",fn_name)); BUG_ON(!dev); BUG_ON(!mpls_dev2mtp(dev)); /* previously held in mpls_tunnel_add_out(...) */ mpls_out_info_release(mpls_dev2mtp(dev)->mtp_moi); mpls_dev2mtp(dev)->mtp_moi = NULL; netif_stop_queue(dev); dev->iflink = 0; MPLS_DEBUG(("%s: exit\n",fn_name)); return 0; } /**** * mpls_tunnel_uninit - Callback called from netdev "unregister_netdevice(dev)" * @dev: virtual device * **/ static void mpls_tunnel_uninit (struct net_device *dev) { mpls_tunnel_unlink(dev); dev_put(dev); } /**** * mpls_tunnel_destructor - say tunnel goodbye. * @dev: mpls tunnel * * This callback gets called when the core system destroys the net_device. * Remember that it was allocated with kmalloc(netdev + privdata), and * dev->priv points to the "extension" (privdata). So we just reset to * NULL. Don't kfree(dev->priv); * * cf. dev.c "It must be the very last action, after this 'dev' may point * to freed up memory." ***/ static void mpls_tunnel_destructor(struct net_device *dev) { dev->priv = NULL; } /**** * mpls_tunnel_xmit - transmit a socket buffer via the device. * @skb: data * @dev: mpls tunnel * * This callback gets called when the core system wants to * send a socket buffer. the "mpls_output2" symbol will take * care of it. This only happens of course if someone set a * valid MOI (e.g. PUSH/.../SET) for the device using IOCTL ***/ static int mpls_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { const char *fn_name = "mpls_tunnel_xmit"; const char *err_nomoi = "MOI was invalid"; struct mpls_push_data mpr = { 0,255,0,1,0 }; MPLS_DEBUG(("%s: enter\n",fn_name)); if(skb->protocol == __constant_htons(ETH_P_MPLS_UC)) { mpr.bos = 0; } else { mpr.bos = 1; } dev->trans_start = jiffies; if (mpls_dev2mtp(dev)->mtp_moi) { mlps_dev2mtp(dev)->stat.tx_packets++; mpls_dev2mtp(dev)->stat.tx_bytes += skb->len; MPLS_DEBUG(("%s: exit\n",fn_name)); return mpls_output2(skb,mpls_dev2mtp(dev)->mtp_moi,&mpr); } dev_kfree_skb(skb); mtp->stat.tx_errors++; MPLS_DEBUG(("%s: exit - %s\n",fn_name, err_nomoi)); return 0; } /**** * mpls_tunnel_get_stats - get sender statistics for this tunnel * @dev: virtual "mpls%d" device. * ***/ static struct net_device_stats* mpls_tunnel_get_stats(struct net_device *dev) { return &((mpls_dev2mtp(dev))->stat); } /**** * mpls_tunnel_ioctl - entry point for ioctls, is a callback of netdevice * @dev: virtual "mpls%d" device. * @ifr: ifreq for the IOCTL request * @cmd: either: * - SIOCMPLSTUNNELADDOUT : Set the MOI to the tunnel * - SIOCMPLSTUNNELDELOUT : remove the MOI from the tunnel * Returns 0 if Ok. -ENOSYS otherwise. ***/ static int mpls_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr,int cmd) { int retval = -ENOSYS; switch (cmd) { case SIOCMPLSTUNNELADDOUT: retval = mpls_tunnel_add_out(dev,ifr); break; case SIOCMPLSTUNNELDELOUT: retval = mpls_tunnel_del_out(dev,ifr); break; default: break; } return retval; } /**** * mpls_tunnel_change_mtu - set a new for the tunnel. * @dev: virtual "mpls%d" device. * @new_mtu: new value * Returns 0 if Ok. -EINVAL otherwise. ***/ static int mpls_tunnel_change_mtu(struct net_device *dev, int new_mtu) { if (new_mtu < 4 || new_mtu > mpls_dev2mtp(dev)->mtp_moi->moi_mtu) return -EINVAL; dev->mtu = new_mtu; return 0; } /*** * mpls_tunnel_init_gen - generic dev->init function * @dev : netdevice object that has been created. * * Init callback for the recently created tunnel. Sets the other callbacks * (transmit -- unidir, we are ~"ingress" --, stats, ioctl, mtu, etc) * and sets the default device (tunnel) attributes. **/ static void mpls_tunnel_init_gen(struct net_device *dev) { /* Callbacks */ dev->uninit = mpls_tunnel_uninit; dev->destructor = mpls_tunnel_destructor; dev->hard_start_xmit = mpls_tunnel_xmit; dev->get_stats = mpls_tunnel_get_stats; dev->do_ioctl = mpls_tunnel_ioctl; dev->change_mtu = mpls_tunnel_change_mtu; // int (*init)(struct net_device *dev); <- set on create // int (*open)(struct net_device *dev); // int (*stop)(struct net_device *dev); /* Properties of mpls%d devices */ dev->type = ARPHRD_MPLS_TUNNEL; dev->hard_header_len = sizeof(u32); dev->mtu = 1500; dev->flags = IFF_NOARP|IFF_POINTOPOINT; dev->iflink = 0; dev->addr_len = 4; } /*** * mpls_tunnel_dev_init(struct net_device *dev) * @dev : netdevice object that has been created. * * The function mpls_tunnel_create sets this function as the init callback * for the created net_device. It will be called by the network core * subsystem. For now, it is just a wrapper. **/ static int mpls_tunnel_dev_init(struct net_device *dev) { mpls_tunnel_init_gen(dev); return 0; } /*** * mpls_tunnel_init() * * Init method called when the module is loaded, initiliazes the * list of created tunnels to zero. **/ static int __init mpls_tunnel_init_module(void) { printk("MPLS %s\n",mpls_tunnel_string); printk("MPLS %s\n",mpls_tunnel_copyright); printk("MPLS version %d.%d%d%d 2003/11/20\n", (MPLS_LINUX_VERSION >> 24) & 0xFF, (MPLS_LINUX_VERSION >> 16) & 0xFF, (MPLS_LINUX_VERSION >> 8) & 0xFF, (MPLS_LINUX_VERSION & 0xFF)); mpls_tunnel_list = NULL; return 0; } /*** * mpls_tunnel_exit() * * Exit method called when the module is unloaded * FIXME : Implement as a work queue ? * * How to do this? we need to destroy all existing tunnels, but we cannot * ReadLock the list of tunnels, since unlink (called from a callback) also * ants to WriteHold the list. **/ static void __exit mpls_tunnel_exit_module(void) { struct net_device *dev = NULL; /* Pointer to the created device */ struct mpls_tunnel_private *ptr; struct ifreq ifr; // This is deadlock zone... for(ptr = mpls_tunnel_list; ptr; ptr = ptr->next) { strcpy(ifr->ifr_name,mpls_mtp2dev(ptr)->name); mpls_tunnel_destroy(&ifr); } printk("MPLS %s exiting\n",mpls_tunnel_string); return; } module_init(mpls_tunnel_init_module); module_exit(mpls_tunnel_exit_module); /**** * EXPORTED SYMBOLS **/ EXPORT_SYMBOL(mpls_tunnel_create); EXPORT_SYMBOL(mpls_tunnel_destroy); EXPORT_SYMBOL(mpls_tunnel_get_by_name); EXPORT_SYMBOL(mpls_tunnel_get); EXPORT_SYMBOL(mpls_tunnel_put); // 8<-----------8<----------8<--------------------------8<-------------------8< // Obsoleted. should be removed. // USE mpls_tunnel_create // USE mpls_tunnel_get // USE mpls_tunnel_get_by_name // USE mpls_tunnel_destroy // 8<-----------8<----------8<--------------------------8<-------------------8< struct net_device* __deprecated mpls_tunnel_locate(struct ifreq *ifr,int create) { BUG(); return NULL; } // 8<-----------8<----------8<--------------------------8<-------------------8< |
|
From: Ramon C. <cas...@in...> - 2003-11-19 23:04:07
|
James/All,
In this issue "mpls_proc.c was sad because his daddy did not offer him a
nice seq_file for christmas".
Attached patch:
mpls-procfs-rewrite-seq_file.diff
* mpls_proc.c, mpls_proc_impl.c (new file)
Ok, this one is big... Major rewrite of the procfs implementation for
mpls-linux. Dumped the existing implementation. I have moved /proc/mpls_*
to /proc/mpls/version, etc.. so this *will* break some userspace apps like
Pim's rsvp-te tunnel (we'll fix them later, it's trivial).
The new code uses seq_files and file operations and is (of course, IMVHO)
much more clean, nice and elegant. We can get rid of all that
"mpls_print_info" stuff.
I have changed some function names in order to respect semantics. We may
need to change net/mpls.h later.
I do have other patchsets, I will submit them slowly. I need to read the
p4 user manual, so I can only checkout the modules that I am interested in
(unless someone offers me a bigger harddisk), and sync to your "head".
*** IMPORTANT ***
I cannot test it. There are major changes here :) you should review them!
(e.g. open vi with your file on the left and open vi with my file on the
right and check line by line ;p)
Best regards,
R.
// -------------------------------------------------------------------
// Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in...
// 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas
8<-----8<-------8<
diff -urN mpls/mpls_proc.c mpls.rcas/mpls_proc.c
--- mpls/mpls_proc.c 2003-11-19 14:17:55.000000000 +0100
+++ mpls.rcas/mpls_proc.c 2003-11-19 23:26:15.741314328 +0100
@@ -1,614 +1,158 @@
-/*
- * MPLS An implementation of MPLS forwarding for the Linux Kernel.
- * MPLS is implemented based off of the IETF drafts:
- * -draft-ietf-mpls-arch-06
- * -draft-ietf-mpls-framework-05
- * -draft-ietf-mpls-label-encaps-07
+/*****************************************************************************
+ * MPLS
+ * An implementation of the MPLS (MultiProtocol Label
+ * Switching) Architecture for Linux.
*
- * It implements:
- * -functions that display the current in and out labels via
- * the proc filesystem
+ * __THIS_FILE__
+ * * ProcFS.
*
- * Authors: James R. Leu, <jl...@mi...>
+ * $Id$
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * Authors:
+ * James Leu <jl...@mi...>
+ * Ramon Casellas <cas...@in...>
*
+ * (c) 1999-2003 James Leu <jl...@mi...>
+ * (c) 2003 Ramon Casellas <cas...@in...>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * $ChangeLog$
+ *****************************************************************************
*/
+#ifdef CONFIG_PROC_FS
+
#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <net/mpls.h>
#include <linux/in.h>
#include <linux/inet.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <net/dst.h>
+#include <net/mpls.h>
-extern struct mpls_tunnel_private* mpls_tunnel_list;
-extern rwlock_t mpls_tunnel_lock;
-extern rwlock_t mpls_mii_lock;
-extern rwlock_t mpls_moi_lock;
-
-struct mpls_print_info {
- char *buffer;
- off_t begin;
- off_t pos;
- int len;
- int length;
- int offset;
+#include "mpls_proc_impl.c"
+
+struct mpls_entry {
+ const char *name;
+ struct file_operations *fops;
};
-static void mpls_adjust_print_info(int size,struct mpls_print_info *p) {
- p->len += size;
- p->pos = p->begin + p->len;
- if(p->pos < p->offset) {
- p->len = 0;
- p->begin = p->pos;
- }
-}
+struct proc_dir_entry *proc_net_mpls;
-static int mpls_check_print_info(struct mpls_print_info *p,int entry_size) {
- int retval = 0;
+static struct file_operations mpls_in_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = mpls_in_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
- if(p->pos >= (p->offset + p->length - entry_size))
- retval = -1;
+static struct file_operations mpls_out_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = mpls_out_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
- return retval;
-}
+static struct file_operations mpls_labelspace_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = mpls_labelspace_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
-static char *mpls_print_label_str(struct mpls_label* ml) {
- static char buffer[16];
+static struct file_operations mpls_tunnel_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = mpls_tunnel_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
- switch(ml->ml_type) {
- case MPLS_LABEL_GEN:
- sprintf(buffer,"gen %d",ml->u.ml_gen);
- break;
- case MPLS_LABEL_ATM:
- sprintf(buffer,"atm %d/%d",ml->u.ml_atm.mla_vpi,
- ml->u.ml_atm.mla_vci);
- break;
- case MPLS_LABEL_FR:
- sprintf(buffer,"fr %d",ml->u.ml_fr);
- break;
- case MPLS_LABEL_KEY:
- sprintf(buffer,"key 0x%08x",ml->u.ml_key);
- break;
- }
- return buffer;
-}
+static struct file_operations mpls_version_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = mpls_version_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
-static int mpls_instruction_print(struct mpls_print_info *p,
- struct mpls_instruction *instr, int length,int dir) {
- int retval = 0;
- int size;
- int i;
-
- for(i=0;i<length;i++) {
- switch(instr[i].mi_opcode) {
- case MPLS_OP_NOP:
- {
- break;
- }
- case MPLS_OP_POP:
- {
- if(!mpls_check_print_info(p,4)) {
- size = sprintf(p->buffer+p->len,"POP ");
- mpls_adjust_print_info(size,p);
- } else {
- retval = -1;
- goto mpls_instr_print;
- }
- break;
- }
- case MPLS_OP_PEEK:
- {
- if(!mpls_check_print_info(p,5)) {
- size = sprintf(p->buffer+p->len,"PEEK ");
- mpls_adjust_print_info(size,p);
- } else {
- retval = -1;
- goto mpls_instr_print;
- }
- break;
- }
- case MPLS_OP_PUSH:
- {
- if(!mpls_check_print_info(p,17)) {
- size = sprintf(p->buffer+p->len,"PUSH(%s) ",
- mpls_print_label_str((struct mpls_label*)instr[i].mi_data));
- mpls_adjust_print_info(size,p);
- } else {
- retval = -1;
- goto mpls_instr_print;
- }
- break;
- }
- case MPLS_OP_DLV:
- {
- if(!mpls_check_print_info(p,4)) {
- size = sprintf(p->buffer+p->len,"DLV ");
- mpls_adjust_print_info(size,p);
- } else {
- retval = -1;
- goto mpls_instr_print;
- }
- break;
- }
- case MPLS_OP_FWD:
- {
- struct mpls_out_info *moi;
- moi = (struct mpls_out_info*)instr[i].mi_data;
- if(!mpls_check_print_info(p,15)) {
- size = sprintf(p->buffer+p->len,"FWD(0x%08x) ",moi->moi_key);
- mpls_adjust_print_info(size,p);
- } else {
- retval = -1;
- goto mpls_instr_print;
- }
- break;
- }
- case MPLS_OP_NF_FWD:
- {
- struct mpls_nfmark_fwd_info *nfi = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,7)) {
- size = sprintf(p->buffer+p->len,"NF_FWD(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_NFMARK_NUM;j++) {
- if(nfi->nfi_moi[j]) {
- if(!mpls_check_print_info(p,27)) {
- size = sprintf(p->buffer+p->len," NFMARK(%d)->OUT(0x%08x)",j,
- nfi->nfi_moi[j]->moi_key);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_DS_FWD:
- {
- struct mpls_dsmark_fwd_info *dfi = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,7)) {
- size = sprintf(p->buffer+p->len,"DS_FWD(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_DSMARK_NUM;j++) {
- if(dfi->dfi_moi[j]) {
- if(!mpls_check_print_info(p,27)) {
- size = sprintf(p->buffer+p->len," DSMARK(%d)->OUT(0x%08x)",j,
- dfi->dfi_moi[j]->moi_key);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_EXP_FWD:
- {
- struct mpls_exp_fwd_info *efi = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,8)) {
- size = sprintf(p->buffer+p->len,"EXP_FWD(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_EXP_NUM;j++) {
- if(efi->efi_moi[j]) {
- if(!mpls_check_print_info(p,26)) {
- size = sprintf(p->buffer+p->len," EXP(%d)->OUT(0x%08x)",j,
- efi->efi_moi[j]->moi_key);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_SET:
- {
- if (dir == MPLS_IN) {
- struct net_device *dev = instr[i].mi_data;
- if(!mpls_check_print_info(p,IFNAMSIZ+6)) {
- size = sprintf(p->buffer+p->len,"SET(%s) ",dev->name);
- mpls_adjust_print_info(size,p);
- }
- } else {
- struct mpls_dst *md = instr[i].mi_data;
- if(!mpls_check_print_info(p,IFNAMSIZ+21)) {
- size = sprintf(p->buffer+p->len,"SET(%s,%u.%u.%u.%u) ",
- md->md_dst->dev->name,
- NIPQUAD(((struct sockaddr_in*)&md->md_nh)->sin_addr.s_addr));
- mpls_adjust_print_info(size,p);
- }
- }
- break;
- }
- case MPLS_OP_SET_TC:
- {
- unsigned short *tc = instr[i].mi_data;
- if(!mpls_check_print_info(p,13)) {
- size = sprintf(p->buffer+p->len,"SET_TC(%04x) ",*tc);
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_SET_DS:
- {
- unsigned char *ds = instr[i].mi_data;
- if(!mpls_check_print_info(p,11)) {
- size = sprintf(p->buffer+p->len,"SET_DS(%02x) ",*ds);
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_SET_EXP:
- {
- unsigned char *exp = instr[i].mi_data;
- if(!mpls_check_print_info(p,11)) {
- size = sprintf(p->buffer+p->len,"SET_EXP(%02x) ",*exp);
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_EXP2TC:
- {
- struct mpls_exp2tcindex_info *e2ti = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,8)) {
- size = sprintf(p->buffer+p->len,"EXP2TC(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_EXP_NUM;j++) {
- if(e2ti->e2t[j]) {
- if(!mpls_check_print_info(p,18)) {
- size = sprintf(p->buffer+p->len," EXP(%d)->TC(%04x)",j,
- e2ti->e2t[j]);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_EXP2DS:
- {
- struct mpls_exp2dsmark_info *e2di = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,8)) {
- size = sprintf(p->buffer+p->len,"EXP2DS(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_EXP_NUM;j++) {
- if(e2di->e2d[j] != 0xFF) {
- if(!mpls_check_print_info(p,18)) {
- size = sprintf(p->buffer+p->len," EXP(%d)->DS(%02x)",j,
- e2di->e2d[j]);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_DS2EXP:
- {
- struct mpls_dsmark2exp_info *d2ei = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,8)) {
- size = sprintf(p->buffer+p->len,"DS2EXP(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_DSMARK_NUM;j++) {
- if(d2ei->d2e[j] != 0xFF) {
- if(!mpls_check_print_info(p,18)) {
- size = sprintf(p->buffer+p->len," DS(%02x)->EXP(%02x)",j,
- d2ei->d2e[j]);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_TC2EXP:
- {
- struct mpls_tcindex2exp_info *t2ei = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,8)) {
- size = sprintf(p->buffer+p->len,"TC2EXP(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_TCINDEX_NUM;j++) {
- if(t2ei->t2e[j] != 0xFF) {
- if(!mpls_check_print_info(p,18)) {
- size = sprintf(p->buffer+p->len," TC(%02x)->EXP(%02x)",j,
- t2ei->t2e[j]);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- case MPLS_OP_NF2EXP:
- {
- struct mpls_nfmark2exp_info *n2ei = instr[i].mi_data;
- int j;
-
- if(!mpls_check_print_info(p,8)) {
- size = sprintf(p->buffer+p->len,"NF2EXP(");
- mpls_adjust_print_info(size,p);
- }
- for(j=0;j<MPLS_NFMARK_NUM;j++) {
- if(n2ei->n2e[j] != 0xFF) {
- if(!mpls_check_print_info(p,18)) {
- size = sprintf(p->buffer+p->len," NF(%02x)->EXP(%02x)",j,
- n2ei->n2e[j]);
- mpls_adjust_print_info(size,p);
- }
- }
- }
- if(!mpls_check_print_info(p,2)) {
- size = sprintf(p->buffer+p->len," ) ");
- mpls_adjust_print_info(size,p);
- }
- break;
- }
- }
- }
-mpls_instr_print:
- return retval;
-}
+static struct mpls_entry mpls_files[] = {
+ {"in", &mpls_in_seq_fops},
+ {"labelspace", &mpls_labelspace_seq_fops},
+ {"out", &mpls_out_seq_fops},
+ {"tunnel", &mpls_tunnel_seq_fops},
+ {"version", &mpls_version_seq_fops},
+};
-static int mpls_print_out_label_node(struct mpls_out_info_node *node,struct mpls_print_info *p) {
- struct mpls_out_info *moi = node->moi;
- int retval = 0;
- int size = 0;
-
- if(!moi) {
- return 0;
- }
-
- if(!mpls_check_print_info(p,39)) {
- size = sprintf(p->buffer+p->len,"0x%08x %lu/%lu/%lu %d ",moi->moi_key,
- moi->moi_packets,moi->moi_bytes,moi->moi_drops,
- atomic_read(&moi->__refcnt));
- mpls_adjust_print_info(size,p);
-
- if(mpls_instruction_print(p,moi->moi_instruction,
- moi->moi_instruction_length,MPLS_OUT)) {
- retval = -1;
- goto mpls_print_out_info_exit;
- }
- if(!mpls_check_print_info(p,1)) {
- size = sprintf(p->buffer+p->len,"\n");
- mpls_adjust_print_info(size,p);
- } else {
- retval = -1;
- }
- } else {
- retval = -1;
- }
-mpls_print_out_info_exit:
- return retval;
-}
-static int mpls_print_in_label_node(struct mpls_in_info_node *node,struct mpls_print_info *p) {
- struct mpls_in_info *mii = node->mii;
- int retval = 0;
- int size = 0;
-
- if(!mii) {
- return 0;
- }
-
- if(!mpls_check_print_info(p,63)) {
- /* print the in label */
- size = sprintf(p->buffer+p->len,"0x%08x %lu/%lu/%lu %s %d %d ",mii->mii_key,
- mii->mii_packets,mii->mii_bytes,mii->mii_drops,
- mpls_print_label_str(&mii->mii_label),mii->mii_labelspace,
- atomic_read(&mii->__refcnt));
- mpls_adjust_print_info(size,p);
-
- /* print intructions */
- if(mpls_instruction_print(p,mii->mii_instruction,
- mii->mii_instruction_length,MPLS_IN)) {
- retval = -1;
- goto mpls_print_in_info_exit;
- }
- if(!mpls_check_print_info(p,1)) {
- size = sprintf(p->buffer+p->len,"\n");
- mpls_adjust_print_info(size,p);
- } else {
- retval = -1;
- }
- } else {
- retval = -1;
- }
-mpls_print_in_info_exit:
- return retval;
+
+
+/****
+ * mpls_procfs_init - Create the corresponding /proc/net/mpls/ entries.
+ *
+ * This function is called on module init (load).
+ * Register mpls in /proc file system
+ ***/
+
+int __init mpls_procfs_init (void)
+{
+ struct proc_dir_entry* dir_ent = NULL;
+ int i=0;
+
+ proc_net_mpls = proc_mkdir("mpls", proc_net);
+ if (proc_net_mpls == NULL)
+ return -1;
+
+ proc_net_mpls->owner = THIS_MODULE;
+
+ for (i=0; i < ARRAY_SIZE(mpls_files); ++i) {
+ dir_ent = create_proc_entry(mpls_files[i].name, 0, proc_net_mpls);
+ if (NULL != dir_ent) {
+ dir_ent->proc_fops = mpls_files[i].fops;
+ }
+ }
+ return 0;
}
-/* -------------------- EXPORTED FUNCTIONS FOLLOW -------------------- */
-int mpls_in_label_info(char *buffer, char **start, off_t offset, int length) {
- struct mpls_print_info print;
+/****
+ * mpls_procfs_exit - Remove the corresponding /proc/net/mpls_ entries.
+ *
+ * This function is called on module exit (removal).
+ * Unregister mpls in /proc file system.
+ **/
+
+void __exit mpls_procfs_exit (void)
+{
+ int i=0;
- print.buffer = buffer;
- print.offset = offset;
- print.length = length;
- print.len = 0;
- print.pos = 0;
- print.begin = 0;
-
- read_lock(&mpls_mii_lock);
-
- RADIX_VISIT_ALL(&mii_tree,mpls_in_info_node,next,MPLS_TREE_BITS,
- mpls_print_in_label_node,&print);
-
- read_unlock(&mpls_mii_lock);
-
- *start = print.buffer + (print.offset - print.begin);
- print.len -= (print.offset - print.begin);
- if(print.len > print.length)
- print.len = print.length;
- if(print.len < 0)
- print.len = 0;
- return print.len;
+ if (proc_net_mpls) {
+ for (i=0; i < ARRAY_SIZE(mpls_files); ++i) {
+ remove_proc_entry(mpls_files[i].name, proc_net_mpls);
+ }
+ remove_proc_entry("mpls",proc_net);
+ proc_net_mpls = NULL;
}
-int mpls_out_label_info(char *buffer, char **start, off_t offset, int length) {
- struct mpls_print_info print;
- print.buffer = buffer;
- print.offset = offset;
- print.length = length;
- print.len = 0;
- print.pos = 0;
- print.begin = 0;
-
- read_lock(&mpls_moi_lock);
-
- RADIX_VISIT_ALL(&moi_tree,mpls_out_info_node,next,MPLS_TREE_BITS,
- mpls_print_out_label_node,&print);
-
- read_unlock(&mpls_moi_lock);
-
- *start = print.buffer + (print.offset - print.begin);
- print.len -= (print.offset - print.begin);
- if(print.len > print.length)
- print.len = print.length;
- if(print.len < 0)
- print.len = 0;
- return print.len;
-}
+#else // !CONFIG_PROC_FS
-int mpls_labelspace_info(char *buffer, char **start, off_t offset, int length) {
- struct mpls_print_info print;
- struct net_device *dev = NULL;
- int labelspace;
- int size = 0;
-
- print.buffer = buffer;
- print.offset = offset;
- print.length = length;
- print.len = 0;
- print.pos = 0;
- print.begin = 0;
-
- read_lock(&dev_base_lock);
- for(dev = dev_base; dev != NULL; dev = dev->next) {
- labelspace = dev->mpls_ptr?((struct mpls_interface*)(dev->mpls_ptr))->labelspace:-1;
- if(labelspace >= 0) {
- if(!mpls_check_print_info(&print,6+IFNAMSIZ)) {
- size = sprintf(print.buffer+print.len,"%s\t%d\t%d\n",dev->name,
- labelspace,atomic_read(&dev->refcnt));
- mpls_adjust_print_info(size,&print);
- } else {
- break;
- }
- }
- }
- read_unlock(&dev_base_lock);
-
- *start = print.buffer + (print.offset - print.begin);
- print.len -= (print.offset - print.begin);
- if(print.len > print.length)
- print.len = print.length;
- if(print.len < 0)
- print.len = 0;
- return print.len;
+inline int __init mpls_procfs_init (void)
+{
+ return 0;
}
-int mpls_tunnel_info(char *buffer, char **start, off_t offset, int length) {
- struct mpls_print_info print;
- struct mpls_tunnel_private *ptr;
- int size;
-
- print.buffer = buffer;
- print.offset = offset;
- print.length = length;
- print.len = 0;
- print.pos = 0;
- print.begin = 0;
-
- write_lock(&mpls_tunnel_lock);
-
- for(ptr = mpls_tunnel_list;ptr;ptr = ptr->next) {
- if(!mpls_check_print_info(&print,9+IFNAMSIZ)) {
- size = sprintf(print.buffer+print.len,"%s\t0x%08x\n",ptr->mtp_dev->name,
- ptr->mtp_moi?ptr->mtp_moi->moi_key:0);
- mpls_adjust_print_info(size,&print);
- } else {
- break;
- }
- }
-
- write_unlock(&mpls_tunnel_lock);
-
- *start = print.buffer + (print.offset - print.begin);
- print.len -= (print.offset - print.begin);
- if(print.len > print.length)
- print.len = print.length;
- if(print.len < 0)
- print.len = 0;
- return print.len;
+inline void __exit mpls_procfs_exit (void)
+{
}
+#endif // CONFIG_PROC_FS
-int mpls_version_info(char *buffer, char **start, off_t offset, int length) {
- struct mpls_print_info print;
- int size;
-
- print.buffer = buffer;
- print.offset = offset;
- print.length = length;
- print.len = 0;
- print.pos = 0;
- print.begin = 0;
-
- if(!mpls_check_print_info(&print,10)) {
- size = sprintf(print.buffer+print.len,"%08x\n", MPLS_LINUX_VERSION);
- mpls_adjust_print_info(size,&print);
- }
-
- *start = print.buffer + (print.offset - print.begin);
- print.len -= (print.offset - print.begin);
- if(print.len > print.length)
- print.len = print.length;
- if(print.len < 0)
- print.len = 0;
- return print.len;
-}
diff -urN mpls/mpls_proc_impl.c mpls.rcas/mpls_proc_impl.c
--- mpls/mpls_proc_impl.c 1970-01-01 01:00:00.000000000 +0100
+++ mpls.rcas/mpls_proc_impl.c 2003-11-19 23:26:15.742314176 +0100
@@ -0,0 +1,391 @@
+/*****************************************************************************
+ * MPLS
+ * An implementation of the MPLS (MultiProtocol Label
+ * Switching) Architecture for Linux.
+ *
+ * __THIS_FILE__
+ * * ProcFS.
+ *
+ * $Id$
+ *
+ * Authors:
+ * James Leu <jl...@mi...>
+ * Ramon Casellas <cas...@in...>
+ *
+ * (c) 1999-2003 James Leu <jl...@mi...>
+ * (c) 2003 Ramon Casellas <cas...@in...>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Changes:
+ * 20031120 RCAS:
+ * Rewritten. Completely. Really. From scratch (well, almost).
+ *****************************************************************************
+ */
+
+extern struct mpls_tunnel_private *mpls_tunnel_list;
+extern rwlock_t mpls_tunnel_lock;
+extern rwlock_t mpls_mii_lock;
+extern rwlock_t mpls_moi_lock;
+
+
+/******************************************************************************
+ * mpls_seq_print_label - pretty print a label to a seq_file
+ * @seq: output stream.
+ * @ml: the label itself
+ *
+ * "All purpose" function. Typically called from the methods below, when
+ * "pretty printing" a MII/MOI.
+ *
+ *****************************************************************************/
+static int mpls_seq_print_label(struct seq_file *seq, struct mpls_label *ml)
+{
+ switch (ml->ml_type) {
+ case MPLS_LABEL_GEN:
+ seq_printf(seq, "gen %d", ml->u.ml_gen);
+ break;
+ case MPLS_LABEL_ATM:
+ seq_printf(seq, "atm %d/%d",
+ ml->u.ml_atm.mla_vpi,
+ ml->u.ml_atm.mla_vci);
+ break;
+ case MPLS_LABEL_FR:
+ seq_printf(seq, "fr %d", ml->u.ml_fr);
+ break;
+ case MPLS_LABEL_KEY:
+ seq_printf(seq, "key 0x%08x", ml->u.ml_key);
+ break;
+ }
+ return buffer;
+}
+
+
+
+/******************************************************************************
+ * Auxiliary macros.
+ *
+ *****************************************************************************/
+#define __mpls_foreach_seqprintf4(NUM, FORMAT,TYPE,FIELD)\
+for (j = 0; j < (NUM); j++) { \
+ if (((TYPE)helper)->(FIELD)[j]) {\
+ seq_printf(seq, (FORMAT), j, ((TYPE)helper)->(FIELD)[j]);\
+ }\
+}
+
+#define __mpls_foreach_seqprintf4_FF(NUM, FORMAT,TYPE,FIELD)\
+for (j = 0; j < (NUM); j++) { \
+ if (((TYPE)helper)->(FIELD)[j] != 0xFF) {\
+ seq_printf(seq, (FORMAT), j, ((TYPE)helper)->(FIELD)[j]);\
+ }\
+}
+
+#define __mpls_foreach_seqprintf5(NUM, FORMAT,TYPE,FIELD,SUBFIELD)\
+for (j = 0; j < (NUM); j++) { \
+ if (((TYPE)helper)->(FIELD)[j]) {\
+ seq_printf(seq, (FORMAT), j, ((TYPE)helper)->(FIELD)[j]->(SUBFIELD));\
+ }\
+}
+
+
+/******************************************************************************
+ * mpls_seq_print_instr - pretty print an instruction to a seq_file
+ * @seq: output stream.
+ * @instr: the instruction array (opcodes to execute for a MII/MOI)
+ * @length: array size
+ * @dir: in or out.
+ *
+ * "All purpose" function. Typically called from the methods below, when
+ * "pretty printing" a MII/MOI.
+ *
+ *****************************************************************************/
+
+static int mpls_seq_print_instr(struct seq_file *seq,
+ struct mpls_instruction *instr, int length, int dir)
+{
+ /* to iterate all the instructions/subs in the array */
+ int i,j;
+
+ /* We will cast these to the required type, according to the opcode */
+ void *helper = NULL;
+ struct mpls_dst *dest = NULL;
+
+ for (i = 0; i < length; i++) {
+ helper = instr[i].mi_data;
+
+ switch (instr[i].mi_opcode) {
+ case MPLS_OP_NOP:
+ break;
+
+ case MPLS_OP_POP:
+ seq_printf(seq,"POP ");
+ break;
+
+ case MPLS_OP_PEEK:
+ seq_printf(seq,"PEEK ");
+ break;
+
+ case MPLS_OP_DLV:
+ seq_printf(seq,"DLV ");
+ break;
+
+ case MPLS_OP_PUSH:
+ seq_printf(seq,"PUSH(");
+ mpls_seq_print_label(seq,(struct mpls_label *)helper);
+ seq_printf(seq,") ");
+ break;
+
+ case MPLS_OP_FWD:
+ seq_printf(seq,"FWD(0x%08x) ",
+ ((struct mpls_out_info*)helper)->moi_key);
+ break;
+
+ case MPLS_OP_NF_FWD:
+ seq_printf(seq, "NF_FWD(");
+ __mpls_foreach_seqprintf5(MPLS_NFMARK_NUM," NFMARK(%d)->OUT(0x%08x) ",
+ (struct mpls_nfmark_fwd_info*),nfi_moi,moi_key);
+ seq_printf(seq," ) ");
+ break;
+
+ case MPLS_OP_DS_FWD:
+ seq_printf(seq, "DS_FWD(");
+ __mpls_foreach_seqprintf5(MPLS_DSMARK_NUM," DSMARK(%d)->OUT(0x%08x) ",
+ (struct mpls_dsmark_fwd_info*),dfi_moi,moi_key);
+ seq_printf(seq," ) ");
+ break;
+
+ case MPLS_OP_EXP_FWD:
+ seq_printf(seq,"EXP_FWD(");
+ __mpls_foreach_seqprintf5(MPLS_EXP_NUM," EXP(%d)->OUT(0x%08x)",
+ (struct mpls_exp_fwd_info*),efi_moi,moi_key);
+ seq_printf(seq," ) ");
+ break;
+
+ case MPLS_OP_SET:
+ if (dir == MPLS_IN) {
+ seq_printf(seq,"SET(%s) ",
+ ((struct net_device*)helper)->name);
+ } else {
+ dest = (struct mpls_dst *)helper;
+ seq_printf(seq,"SET(%s,%u.%u.%u.%u) ",
+ dest->md_dst->dev->name,
+ NIPQUAD(((struct sockaddr_in*)&dest->md->md_nh)->sin_addr.s_addr));
+ }
+ break;
+
+ case MPLS_OP_SET_TC:
+ seq_printf(seq, "SET_TC(%04x) ", *((unsigned short*)helper));
+ break;
+
+ case MPLS_OP_SET_DS:
+ seq_printf(seq, "SET_DS(%02x) ", *((unsigned char*)helper));
+ break;
+
+ case MPLS_OP_SET_EXP:
+ seq_printf(seq, "SET_EXP(%02x) ", *((unsigned char*)helper));
+ break;
+
+ case MPLS_OP_EXP2TC:
+ seq_printf(seq,"EXP2TC(");
+ __mpls_foreach_seqprintf4(MPLS_EXP_NUM," EXP(%d)->TC(%04x)",
+ (struct mpls_exp2tcindex_info*),e2t);
+ seq_printf(seq," ) ");
+ break;
+
+ case MPLS_OP_EXP2DS:
+ seq_printf(seq,"EXP2DS(");
+ __mpls_foreach_seqprintf4_FF(MPLS_EXP_NUM, " EXP(%02x)->DS(%02x)",
+ (struct mpls_exp2dsmark_info*),e2d);
+ seq_printf(seq," ) ");
+ break;
+
+ case MPLS_OP_DS2EXP:
+ seq_printf(seq,"DS2EXP(");
+ __mpls_foreach_seqprintf4_FF(MPLS_EXP_NUM, " DS(%d)->EXP(%02x)",
+ (struct mpls_dsmark2exp_info*),d2e);
+ seq_printf(seq," ) ");
+ break;
+
+ case MPLS_OP_TC2EXP:
+ seq_printf(seq,"TC2EXP(");
+ __mpls_foreach_seqprintf4_FF(MPLS_TCINDEX_NUM, " TC(%d)->DS(%02x)",
+ (struct mpls_tcindex2exp_info*),t2e);
+ seq_printf(seq," ) ");
+ break;
+
+ case MPLS_OP_NF2EXP:
+ seq_printf(seq,"NF2EXP(");
+ __mpls_foreach_seqprintf4_FF(MPLS_NFMARK_NUM, " NF(%02x)->EXP(%02x)",
+ (struct mpls_nfmark2exp_info*),n2e);
+ seq_printf(seq," ) ");
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+
+/******************************************************************************
+ * mpls_print_out_label_node - callback function when visiting all the nodes
+ * in the Input (MII) radix tree.
+ *
+ * @node: node in the radix tree.
+ * @seq: output stream
+ *
+ *****************************************************************************/
+
+static int mpls_print_out_label_node(struct mpls_out_info_node *node,
+ struct seq_file *seq)
+{
+ struct mpls_out_info *moi = node->moi;
+
+ if (!moi) return 0;
+
+ seq_printf(seq, "0x%08x %lu/%lu/%lu %d ",
+ moi->moi_key, moi->moi_packets, moi->moi_bytes,
+ moi->moi_drops, atomic_read(&moi->__refcnt));
+
+ mpls_seq_print_instr(seq, moi->moi_instruction,
+ moi->moi_instruction_length, MPLS_OUT);
+
+ return 0;
+}
+
+
+
+/******************************************************************************
+ * mpls_print_out_label_node - callback function when visiting all the nodes
+ * in the Input (MII) radix tree.
+ *
+ * @node: node in the radix tree.
+ * @seq: output stream
+ *
+ *****************************************************************************/
+
+static int mpls_print_in_label_node(struct mpls_in_info_node *node,
+ struct seq_file *seq)
+{
+ struct mpls_in_info *mii = node->mii;
+
+ if (!mii) return 0;
+
+ seq_printf(seq, "0x%08x %lu/%lu/%lu %s %d %d \n",
+ mii->mii_key,
+ mii->mii_packets,
+ mii->mii_bytes,
+ mii->mii_drops,
+ mpls_seq_print_label(&mii->mii_label),
+ mii->mii_labelspace,
+ atomic_read(&mii->__refcnt));
+
+ mpls_seq_print_instr(seq, mii->mii_instruction,
+ mii->mii_instruction_length, MPLS_IN);
+
+ return 0;
+}
+
+
+/******************************************************************************
+ * *_seq_show methods for seq_file ops.
+ *****************************************************************************/
+
+/* Visit all the Input Radix Tree nodes and dump each node
+ This is done under a readers' lock. */
+static int mpls_in_seq_show(struct seq_file *seq, void *v)
+{
+ read_lock(&mpls_mii_lock);
+ RADIX_VISIT_ALL(&mii_tree, mpls_in_info_node, next,
+ MPLS_TREE_BITS, mpls_print_in_label_node, seq);
+ read_unlock(&mpls_mii_lock);
+ return 0;
+}
+
+/* Visit all the Output Radix Tree nodes and dump each node
+ This is done under a readers' lock. */
+static int mpls_out_seq_show(struct seq_file *seq, void *v)
+{
+ read_lock(&mpls_moi_lock);
+ RADIX_VISIT_ALL(&moi_tree, mpls_out_info_node, next,
+ MPLS_TREE_BITS, mpls_print_out_label_node, seq);
+ read_unlock(&mpls_moi_lock);
+ return 0;
+}
+
+/* Iterate all net devices (readers dev_base_lock) and dump
+ the label space if the netdevice is MPLS enabled */
+static int mpls_labelspace_seq_show(struct seq_file *seq, void *v)
+{
+ struct net_device *dev = NULL;
+ struct mpls_interface *mpls_if = NULL;
+ int labelspace;
+
+ read_lock(&dev_base_lock);
+ for (dev = dev_base; dev != NULL; dev = dev->next) {
+ labelspace = -1;
+ mpls_if = (struct mpls_interface*) dev->mpls_ptr;
+ if (mpls_if)
+ labelspace = mpls_if->labelspace;
+ if (labelspace >= 0)
+ seq_printf(seq,"%s\t%d\t%d\n", dev->name,
+ labelspace, atomic_read(&dev->refcnt));
+ }
+ read_unlock(&dev_base_lock);
+ return 0;
+}
+
+/* Iterate all virtual net devices (mpls%d) and dump them */
+static int mpls_tunnel_seq_show(struct seq_file *seq, void *v)
+{
+ struct mpls_tunnel_private *ptr = NULL;
+
+ read_lock(&mpls_tunnel_lock);
+ for (ptr = mpls_tunnel_list; ptr; ptr = ptr->next) {
+ seq_printf(seq, "%s\t0x%08x\n", ptr->mtp_dev->name,
+ ptr->mtp_moi ? ptr->mtp_moi->moi_key : 0);
+ }
+ read_unlock(&mpls_tunnel_lock);
+ return 0;
+}
+
+/* Dump version... ohh yeah! */
+static int mpls_version_seq_show(struct seq_file *seq, void *v)
+{
+ seq_printf(seq, "%08x\n", MPLS_LINUX_VERSION);
+ return 0;
+}
+
+
+/******************************************************************************
+ * *_seq_open methods for seq_file ops.
+ *****************************************************************************/
+
+static int mpls_in_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mpls_in_seq_show, NULL);
+}
+
+static int mpls_out_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mpls_in_seq_show, NULL);
+}
+
+static int mpls_labelspace_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mpls_labelspace_seq_show, NULL);
+}
+
+static int mpls_tunnel_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mpls_tunnel_seq_show, NULL);
+}
+
+static int mpls_version_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mpls_version_seq_show, NULL);
+}
+
+
|
|
From: Ramon C. <cas...@in...> - 2003-11-19 22:49:24
|
James/All, Attached patch: mpls-mpls_if.c-cleanup-comment.diff * mpls_if.c : clean up, format and comment. Nothing big. Remark: * This patch and the one that follows should apply nicely to your p4 depot. Synced today (although I'll talk to you in private email, since your depot eat my disk space :) for kernel 2.6.0-test9 * Since your p4 version does not (yet) compile, I cannot test it. For this early stages (for me at least), I would really like you to "peer-review" them. // ------------------------------------------------------------------- // Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in... // 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas 8<-----8<-------8< diff -urN mpls/mpls_if.c mpls.rcas/mpls_if.c --- mpls/mpls_if.c 2003-11-19 14:17:48.000000000 +0100 +++ mpls.rcas/mpls_if.c 2003-11-19 23:24:12.307079184 +0100 @@ -1,91 +1,149 @@ -/* - * MPLS An implementation of MPLS forwarding for the Linux Kernel. - * MPLS is implemented based off of the IETF drafts: - * -draft-ietf-mpls-arch-06 - * -draft-ietf-mpls-framework-05 - * -draft-ietf-mpls-label-encaps-07 - * - * It implements: - * -interface specific settings for MPLS - * - * Authors: James R. Leu, <jl...@mi...> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. +/***************************************************************************** + * MPLS + * An implementation of the MPLS (MultiProtocol Label + * Switching) Architecture for Linux. * + * __THIS_FILE__ + * * Allocation/Deallocation of per netdevice MPLS private data + * (labelspace) + * * Query/Update netdevice label space functions. + * + * $Id$ + * + * Authors: + * James Leu <jl...@mi...> + * Ramon Casellas <cas...@in...> + * + * (c) 1999-2003 James Leu <jl...@mi...> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * $ChangeLog$ + ***************************************************************************** */ #include <asm/uaccess.h> #include <linux/netdevice.h> #include <net/mpls.h> -int mpls_get_labelspace(struct mpls_labelspace_req *req) { - const char *fn_name = "mpls_get_labelspace"; - struct net_device *dev; - int result = -1; - - MPLS_DEBUG(("%s: enter\n",fn_name)); - if(req) { - dev = dev_get_by_index(req->mls_ifindex); - if(dev) { - if (dev->mpls_ptr) { - req->mls_labelspace = - ((struct mpls_interface*)(dev->mpls_ptr))->labelspace; - } else { - req->mls_labelspace = -1; - } - result = 0; - dev_put(dev); - } - } - MPLS_DEBUG(("%s: exit\n",fn_name)); - return result; + + +/**** + * mpls_create_if_info - allocate memory for the MPLS net_device extension + * + * Returns a pointer to the allocated struct. + ***/ + + +struct mpls_interface *mpls_create_if_info(void) +{ + struct mpls_interface *mpls_if = NULL; + + mpls_if = + (struct mpls_interface *) + kmalloc(sizeof(struct mpls_interface), GFP_ATOMIC); + if (NULL == mpls_if) + return NULL; + + memset(mpls_if, 0, sizeof(struct mpls_interface)); + mpls_if->labelspace = -1; + INIT_LIST_HEAD(&(mpls_if->list_out)); + INIT_LIST_HEAD(&(mpls_if->list_in)); + return mpls_if; } -void *mpls_create_if_info(void) { - struct mpls_interface *mpls_if; - mpls_if = (struct mpls_interface*)kmalloc(sizeof(struct mpls_interface), - GFP_ATOMIC); - memset(mpls_if,0,sizeof(*mpls_if)); - mpls_if->labelspace = -1; - INIT_LIST_HEAD(&mpls_if->list_out); - INIT_LIST_HEAD(&mpls_if->list_in); - return (void*)mpls_if; + + + +/**** + * mpls_delete_if_info - free memory for the MPLS net_device extension + * + * Deallocation of MPLS netdev extensions. + * + ***/ + +void mpls_delete_if_info(struct mpls_interface *mpls_if) +{ + kfree(mpls_if); } -void mpls_delete_if_info(struct mpls_interface* mpls_if) { - kfree(mpls_if); + + + +/**** + * mpls_get_labelspace - Get the label space for the interface + * + * @req: mpls_labelspace_req struct with the query data. In particular, + * contains the interface index in req->mls_ifindex. + * + * Returns 0 on sucess and sets the label space for the netdevice in + * req->mls_ifindex. The labelspace in req->mls_ifindex may be -1 if MPLS + * was not active on the interface. + ***/ + +int mpls_get_labelspace(struct mpls_labelspace_req *req) +{ + struct net_device *dev = NULL; + struct mpls_interface *mpls_ptr = NULL; + BUG_ON(NULL == req); + + dev = dev_get_by_index(req->mls_ifindex); + if (NULL == dev) { + return -1; + } + + mpls_ptr = (struct mpls_interface *) dev->mpls_ptr; + req->mls_labelspace = (mpls_ptr) ? mpls_ptr->labelspace : -1; + dev_put(dev); + return 0; } -int mpls_set_labelspace(struct mpls_labelspace_req *req) { - const char *fn_name = "mpls_set_labelspace"; - struct net_device *dev; - int result = -1; - - MPLS_DEBUG(("%s: enter\n",fn_name)); - if(req) { - MPLS_DEBUG(("%s: labelspace(%d)\n",fn_name,req->mls_labelspace)); - if((dev = dev_get_by_index(req->mls_ifindex))) { - if (!dev->mpls_ptr) { - dev->mpls_ptr = mpls_create_if_info(); - if (!dev->mpls_ptr) { - dev_put(dev); - return -ENOMEM; - } - } - if (req->mls_labelspace == -1) { - mpls_delete_if_info(dev->mpls_ptr); - dev->mpls_ptr = NULL; - } else { - ((struct mpls_interface*)(dev->mpls_ptr))->labelspace = - req->mls_labelspace; - } - result = 0; - dev_put(dev); - } - } - MPLS_DEBUG(("%s: exit\n",fn_name)); - return result; + + +/**** + * mpls_set_labelspace - Set a label space for the interface. + * + * @req: mpls_labelspace_req struct with the update data. In particular, + * contains the interface index in req->mls_ifindex, and the new + * labelspace in req->mls_labelspace. + * + * This function assigns a label space to a particular net device. In + * the current implementation, the netdev struct is extended with a + * mpls_ptr to hold mpls data, which is dynamically allocated here, + * using mpls_create_if_info(). + * + * Returns 0 on success. + ***/ + +int mpls_set_labelspace(struct mpls_labelspace_req *req) +{ + const char *fn_name = "mpls_set_labelspace"; + struct net_device *dev = NULL; + struct mpls_interface *mpls_ptr = NULL; + BUG_ON(NULL == req); + + dev = dev_get_by_index(req->mls_ifindex); + if (NULL == dev) + return -1; + + if ((!dev->mpls_ptr) && (req->mls_labelspace != -1)) { + dev->mpls_ptr = (void *) mpls_create_if_info(); + if (!dev->mpls_ptr) { + dev_put(dev); + return -ENOMEM; + } + /* Actual assignment happens here */ + mpls_ptr = (struct mpls_interface *) dev->mpls_ptr; + mpls_ptr->labelspace = req->mls_labelspace; + } + + if ((-1 == req->mls_labelspace) && (dev->mpls_ptr)) { + mpls_delete_if_info(dev->mpls_ptr); + dev->mpls_ptr = NULL; + } + dev_put(dev); + return 0; } |
|
From: Ramon C. <cas...@in...> - 2003-11-19 17:44:13
|
On 19 Nov 2003, jamal wrote:
> Hi Ramon,
>
> Give me a few days; i need to get it to some sane level and would like
> to review with Dave first then James.
> Your interest is highly appreaciated.
Hi Jamal,
You both take your time, good things come to those who wait :)... In fact,
I didn't mean to put *any* kind of pressure on of you. It's my fault,
since I somehow assumed that Dave's port was stalled (the line
"should have something in the tree next week" has been in should-fix for
some time :)), and I started working on the forwarding/data plane. Well,
at least I have a good understanding of James' implementation...
The only thing I want is just to avoid duplicating efforts. So I'll wait
until your convenience ("when it's ready").
On the other hand, I have some patches that apply to James implementation
(e.g. _RX_DROP should be XMIT_DROP in *_output, or use
dev_alloc_name_locked in mpls_tunnel,...) but since Dave is rewritting,
should I drop these?
Best Regards,
R.
|
|
From: Doerfler, R. <Ric...@sc...> - 2003-11-18 18:23:11
|
Hello everybody, this is the next try to get the mplsd running: Zebra and ospfd seem to run properly... I can do "sho ip ospf route" in the ospfd and get good looking results. Even in the linux prompt the command route -n shows that ospf works... =20 Now the difficult part... I start the mplsd and get the output which I attached in the debug.log = file. The initialization process seem to work but at the end it terminates = with a segmentation fault... What is wrong? =20 I also attached copies of my .conf (zebra, ospfd, mplsd) in this = debug.log file. =20 To imagine my situation: I have two computers for the test: A: three network interfaces but only eth0 is connected to the network... eth0: 192.168.0.1 eth1: 192.168.1.2 eth2: 192.168.2.3 then the dummy0 interface which I created with modprobe dummy has the = ip address: 10.0.0.1 =20 B two network interfaces but only eth0 is connected to the network eth0: 192.168.0.7 eth1: 192.168.8.8 then the dummy0 interface with the ip address: 10.0.0.3 =20 =20 there is another computer in the network but there is no zebra and no = ospfd running on it.... I just want to test it with the other two PCs =20 C three network interface but only eth0 is connected to the network... eth0: 192.168.0.4 eth1: 192.168.1.5 eth2: 192.168.2.6 =20 =20 =20 Can someone help me with this strange problem? Did I do something wrong during the configuration? The goal is to have lsps created dynamically... The static way which is dicribed on the page http://mpls-linux.sf.net <http://mpls-linux.sf.net> works, but I don't want to enter the lsp = for each path.... =20 =20 I am very thankful for any help... =20 =20 Richard D=F6rfler =20 .............................................. Richard D=F6rfler Siemens Corporate Research 755 College Road East Princeton, NJ 08540 Tel: (609) 734 6500 Ext. 2210 Fax: (609) 734 6565 =20 |
|
From: Doerfler, R. <Ric...@sc...> - 2003-11-18 16:05:38
|
Hello,
Is there another way to connect to the perforce developement tree or to
download from because the administrators from our network don't allow =
me to
use this perforce programm.
There is another mpls question:
We want to try to split up a voice-over-ip-stream into 2 tcp streams.
Is there a way to have two (or more) different lsp's for these streams =
on
the path?
Or other suggestions?
pic:
_____________stream1_(lsp1)____
A < _____stream2_(lsp2)____________ > B
This don't have to be only two Computers, just two different paths from =
A to
B.
MPLS Setup Question:
I have the ospfd and the zebra daemon running...
When I now want to start the Mpls daemon, what labelspace do I have to =
set?
It seems that the daemon won't start with a "mpls labelspace 0".
When I start the daemons with labelspace set to 1 or s.th else, the =
daemons
start on the two computers but crash on their own after a while.
Occasionally they don't crash and I am able to telnet to the daemons...
When I do sho ldp neighbor,=20
both computers recognize each other, but the message of "sho ldp =
neighbor"
is:
>
Peer LDP Ident: 10.0.0.1:0; Local LDP Ident: 10.0.0.3:1
TCP connection: n/a
State: dicovery; Msgs sent/recv: -/-;
Up time: -
LDP discovery sources:
eth0
>
When I do a "sho ldp discovery" the program terminates itself...
I already sent my config files in thread:
<http://sourceforge.net/mailarchive/forum.php?thread_id=3D3451819&forum_=
id=3D505
1>
I would appreciate some help...
Thanks!
Richard D=F6rfler
______________________________
Richard D=F6rfler
Siemens Corporate Research
755 College Road East
Princeton, NJ 08540
Tel: (609) 734 6500 Ext. 2210
Fax: (609) 734 6565
|
|
From: Ramon C. <cas...@in...> - 2003-11-18 10:27:54
|
On Tue, 18 Nov 2003, Vilyan Dimitrov wrote:
> Hi all,
>
>
> James, here are my 2 cents.
Hi Vilyan,
This was fixed in my yesterday's path:
+/*****
+ * Packet Type for MPLS Unicast Traffic register info.
+ *
+ **/
+static struct packet_type mpls_uc_packet_type = {
+ .type = __constant_htons(ETH_P_MPLS_UC), /* MPLS Unicast
PID */
+ .dev = NULL, /* All devices
*/
+ .func = mpls_rcv,
+#if LINUX_VERSION_CODE > 0x020575
+ .af_packet_priv = NULL,
+ .list = NULL,
+#endif
+};
+
However, I am syncing with p4 and eventually waiting for davem
implementation. I will then port my patchset to the latest James version.
Other things that are worth noting:
This could replace mpls_ref.c
+/****************************************************************************
+ * REFERENCE COUNT MANAGEMENT
+ *
+ *
+ *
+ *
+
****************************************************************************/
+
+/* Hold */
+#define mpls_in_info_hold(mii) \
+BUG_ON(!mii);\
+ atomic_inc(&mii->__refcnt);\
+
+#define mpls_out_info_hold(moi) \
+ BUG_ON(!moi);\
+ atomic_inc(&moi->__refcnt);\
+
+#define mpls_label_hold(label) \
+ BUG_ON(!ml);\
+ atomic_inc(&label->__refcnt);\
+
+#define mpls_dst_hold(dst) \
+ BUG_ON(!dst);\
+ atomic_inc(&dst->__refcnt);\
+
+
+/* Release */
+#define mpls_in_info_release(mii) \
+ BUG_ON(!mii);\
+ if (atomic_dec_and_test(&mii->__refcnt))\
+ __mpls_del_in_label(mii);
+
+#define mpls_out_info_release(moi) \
+BUG_ON(!moi);\
+ if (atomic_dec_and_test(&moi->__refcnt))\
+ __mpls_del_out_label(moi);
+
+#define mpls_label_release(label) \
+BUG_ON(!label);\
+ if (atomic_dec_and_test(&label->__refcnt))\
+ kmem_cache_free(mpls_label_cachep,ml);
+
+#define mpls_dst_release(md) \
+BUG_ON(!md);\
+ if (atomic_dec_and_test(&md->__refcnt))\
+{\
+ if (md->md_dst)\
+ dst_destroy(md->md_dst);\
+ kfree(md);\
+}
+
P4 is sloooooow :))) and James has done a lot of work to download, but
I'll keep you posted,
Regards,
R.
|
|
From: Vilyan D. <vdi...@ne...> - 2003-11-18 10:14:01
|
Hi all,
James, here are my 2 cents.
First, we need some config:
diff -rNu linux-2.6.0-test9/net/Kconfig linux-2.6.0-test9-mpls/net/Kconfig
--- linux-2.6.0-test9/net/Kconfig 2003-10-25 21:42:51.000000000 +0300
+++ linux-2.6.0-test9-mpls/net/Kconfig 2003-11-10 12:57:58.000000000 +0200
@@ -561,6 +561,14 @@
If unsure, say N.
+config MPLS
+ bool "Multi Protocol Label Switching - MPLS"
+ depends on EXPERIMENTAL
+ ---help---
+ Multi Protocol Label Switching (MPLS)
+
+ If unsure, say N.
+
config NET_FASTROUTE
bool "Fast switching (read help!)"
depends on EXPERIMENTAL
diff -rNu linux-2.6.0-test9/net/ipv4/netfilter/Kconfig
linux-2.6.0-test9-mpls/net/ipv4/netfilter/Kconfig
--- linux-2.6.0-test9/net/ipv4/netfilter/Kconfig 2003-10-25
21:44:33.000000000 +0300
+++ linux-2.6.0-test9-mpls/net/ipv4/netfilter/Kconfig 2003-11-10
13:01:40.000000000 +0200
@@ -466,6 +466,14 @@
To compile it as a module, choose M here. If unsure, say N.
+config IP_NF_TARGET_MPLS
+ tristate "MPLS target support"
+ depends on IP_NF_MANGLE && MPLS
+ help
+ This option adds a `MPLS' target.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config IP_NF_TARGET_CLASSIFY
tristate "CLASSIFY target support"
depends on IP_NF_MANGLE
There are changes in kernel Makefiles. Here is new way:
diff -rNu linux-2.6.0-test9/net/mpls/Makefile
linux-2.6.0-test9-mpls/net/mpls/Makefile
--- linux-2.6.0-test9/net/mpls/Makefile 1970-01-01 02:00:00.000000000 +0200
+++ linux-2.6.0-test9-mpls/net/mpls/Makefile 2003-11-10
12:19:58.000000000 +0200
@@ -0,0 +1,10 @@
+#
+# Makefile for the Linux MPLS layer.
+#
+
+obj-$(CONFIG_MPLS) += mpls.o
+
+mpls-y := mpls_if.o mpls_in_info.o mpls_init.o mpls_input.o \
+ mpls_ioctls.o mpls_opcode.o mpls_out_info.o mpls_output.o \
+ mpls_proc.o mpls_ref.o mpls_utils.o mpls_tunnel.o
+
And again this is oldfashioned:
struct packet_type mpls_uc_pt =
{
__constant_htons(ETH_P_MPLS_UC),
NULL, /* All devices */
mpls_rcv,
(void*)1,
NULL,
};
#if 0
struct packet_type mpls_mc_pt =
{
__constant_htons(ETH_P_MPLS_MC);
NULL, /* All devices */
mpls_mc_rcv,
(void*)1,
NULL,
};
#endif
It must be something like:
struct packet_type mpls_uc_pt =
{
.type = __constant_htons(ETH_P_MPLS_UC),
.dev = NULL, /* All devices */
.func = mpls_rcv,
/* ??? .af_packet_priv = (void*)1, */
};
--
Regards,
Vilyan Dimitrov
Network Administrator
Net Is Sat Ltd.
|
|
From: James R. L. <jl...@mi...> - 2003-11-18 00:44:50
|
Hello, I'm glad to hear that you are willing to help out in the porting effort. I have already started the proccess and have the existing 1.172 code compiling on 2.6. I'm in the process of re-writing the IPv4 to MPLS redirection. (which was one of davem's major complaints). The best way to get involved in the 'code' side of things it to use p4. As far as documentation goes, anything you can provide is better then what is there (none). On Tue, Nov 18, 2003 at 01:09:31AM +0100, Ramon Casellas wrote: > > > Hi all, > > After having spend some time using mpls-linux in the framework of some > student projects that I manage (in order to evaluate the performance of > protocols and algorithms like CSPF or MPLS load sharing), I have decided > to work on the project, and the first thing I wanted to do is to port the > kernel patch to 2.6 (I am only interested by now in the forwarding plane, > and not in userspace apps and signaling protocols like > MP-iBG/Zebra/RSVP-TE, etc.), focusing on cleaning up the current > implementation, and documenting along the way :) > > Remark: I have been working with the latest official release mpls 1.1. > (1.172). Of course there is a lot to be done, but, as per Mantainers' : " > Try to release a few ALPHA test versions to the net. Announce them onto > the kernel channel and await results" > > Please, bear with me. I have spent only four days looking and changing > the code :)) and I'm relatively new to linux kernel development. > > > > Objectives: > ----------------- > > * Document. Write something like a developer's guide, documenting the > whole MPLS subsystem, with short references to the Linux kernel networking > core API (e.g. void dev_add_pack(struct packet_type *pt)). Describe not > only each function and its arguments, but be more pedagogic (the lack of > documentation of the existing implementation is an entry barrier). Explain > the subsystem parts and draw execution paths/flows, etc. Most students are > *afraid* of digging in kernel code. The ultimate goal is to have a > platform with quagga (OSPF-TE/MP-iBGP) and the corresponding signaling > protocols (RSVP-TE, CR-LDP,LMP), with advanced MPLS-TE features, like > re-routing and protection switching, bu before that I'd like to work in > order to make the linux-kernel implementation rock solid. > > > Some docs have been done: > http://perso.enst.fr/~casellas/mpls-linux/index.html More to come :) > > > > > * Analysis of the existing implementation: can it be simplified? * > Synchronize. Is anyone working on this? Let us not reinvent the wheel :) > > citing Dave Miller (should-fix). "Real serious use of IPSEC is hampered by > lack of MPLS support. MPLS is a switching technology that works by > switching based upon fixed length labels prepended to packets. Many > people use this and IPSEC to implement VPNs over public networks, it is > also used for things like traffic engineering. > > Anyways, an existing (crappy) implementation exists. I've almost > completed a rewrite, I should have something in the tree next week." > > > > I'd like to know what comments does Mr. Miller have, and of course, if he > is working on something similar. What does he consider crappy (the MII/MOI > Radix Trees , the Opcode and instructions, code quality, lack of > comments/documentation / etc???) > > > > > > * When porting the existing 2.4 implementation try to be as little > intrusive as possible. We should make an effort not to modify the core > parts of the system. Some things that we should think about: > > - Adding a new data field to net_device: it has been done in 2.4 > (void* mpls_ptr) just like other subsystems. Maybe we can find a > way by using only private data. > > > - Forwarding Information Base / Routing Tables, etc. Again, the > 2.4 version patches some core parts like include/net/ip.h, ip_fib and > similar, adding new data fields to core structs. Fortunately some chunks > are no longer needed, since they have been added to the mainstream kernel > (e.g. ETH_P_MPLS_UC). Unfortunately, I'm not very aware of 2.6 changes > (yet) and some chunks do not apply cleanly, e.g: > --- linux-kernel/include/net/ip.h Sat Aug 24 00:22:09 2002 > +++ mpls-kernel-fixes/include/net/ip.h Wed Nov 13 19:38:10 2002 > @@ -162,9 +162,9 @@ > static inline int ip_send(struct sk_buff *skb) > > > - Side effects. chunks like > --- linux-kernel/net/core/neighbour.c Sat Aug 24 00:22:26 2002 > +++ mpls-kernel-fixes/net/core/neighbour.c Tue Nov 12 20:00:46 2002 > @@ -952,7 +952,7 @@ > 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); > + neigh_hh_init(neigh, dst, skb->protocol); > > May have some serious side effects to other networking subsystems. > In the following, I'd like to discuss and find a consensus. > > > > What has been done > ------------------------ > > * I took the 2.4 1.127 patch and cleaned it up, formatted the code, and > added comments in the parts that I did understand (and of course, > introducing some new obscure and difficult to debug bugs in the way). > > * Ported the code to 2.6.0-bk22, latest version as of today. > > * The patch is *alpha* quality. In fact, it compiles, but kernel oopses on > boot. I still don't know if it's my fault (definitely the most probable > option) or because I just took the bk22 version in order to have the > latest patches to the net subsystem. > > * THE PATCH REQUIRES intensive "peer review", I have made some arbitrary > changes in the places that the 2.6.0 has changed with regard to 2.4 (for > example, 2.6 has no "key" in the rtable struct). dst_entrys and so on... > (James I would really appreciate it if you could take the time to review > it) > > > > The actual patch is at: > http://perso.enst.fr/~casellas/mpls-linux/linux-2.6.0-test9-bk22-mpls.diff > > > > Known issues and ToDOs > ----------------------- > > * The current (2.4. 1.172) has been implemented as "built-in", and lacks > all the "exit" functions. The MPLS subsystem MUST be modular, at least, > with mpls.ko and mpls_tunnel.ko. Care must be taken in order to leave the > kernel "clean" on module removal. > > * Some parts (updtaing statistics or mpls_input) could be implemented as > BH (work queues or whatever). > > * The actual procfs implementation (cf. mpls_proc) should be moved to > sysfs. > > * The Radix tree approach is cumbersome, I should review some of James' > design decisions. The semantics of mpls_label, mpls_push_data mpls_key's > are a little confusing. There is no exact "label entry" as described in > the RFC. > > * The mpls_instruction{build, copy, offer, scratch,...} is complicated. > There are some 200-line functions that should be split. > > * Some "key" variables are declared "unsigned int", which may break in > other archs. Should use u_int32_t where appropriate. > > * Audit the code for SMP. > > > * Some parts are not clear to me: > > - why do we copy structs around (e.g. in mpls_set_in_label_instructions)? > memcpy(&mir,in,sizeof(struct mpls_instruction_req)); > > - What's the difference between mpls_del_in_label and > __mpls_del_in_label? When do we call __mpls_del_in_label? > > - Why mpls_instruction_copy copies only the addresses and does not > increase the refcount of data? (pointer aliasing) > > - struct net_device* mpls_tunnel_get_by_name (const char* name), > it just iterates the list of netdevs, and returns a pointer,but it breaks > the semantics of get/put. why there is no reference counting here? > > - A lot of code is just there to check if the arguments are NULL > or not. Maybe we should fix the callers, and put some temporary > BUG_ON(NULL == dev). For most functions, having NULL as an argument is not > a valid option. > > > * Some parts are still a little obscure, like copying around struct > mpls_label just to obtain a key. > > > * Rough corners :) > > if [ -r System.map ]; then /sbin/depmod -ae -F System.map 2.6.0-test9-bk22-mpls; fi > WARNING: /lib/modules/2.6.0-test9-bk22-mpls/kernel/net/ipv4/netfilter/ipt_MPLS.ko needs unknown symbol mpls_output > WARNING: /lib/modules/2.6.0-test9-bk22-mpls/kernel/net/ipv4/netfilter/ipt_MPLS.ko needs unknown symbol mpls_set_nexthop > > > > > > Of course, your comments are most welcome, and I plan to keep on working > on it. Do not hesitate to contact me if you want me to keep you posted. > > > Regards, > > Ramon > > > > // ------------------------------------------------------------------- > // Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in... > // 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas > > > > > ------------------------------------------------------- > This SF. Net email is sponsored by: GoToMyPC > GoToMyPC is the fast, easy and secure way to access your computer from > any Web browser or wireless device. Click here to Try it Free! > https://www.gotomypc.com/tr/OSDN/AW/Q4_2003/t/g22lp?Target=mm/g22lp.tmpl > _______________________________________________ > mpls-linux-general mailing list > mpl...@li... > https://lists.sourceforge.net/lists/listinfo/mpls-linux-general -- James R. Leu jl...@mi... |
|
From: Ramon C. <cas...@in...> - 2003-11-18 00:09:39
|
Hi all, After having spend some time using mpls-linux in the framework of some student projects that I manage (in order to evaluate the performance of protocols and algorithms like CSPF or MPLS load sharing), I have decided to work on the project, and the first thing I wanted to do is to port the kernel patch to 2.6 (I am only interested by now in the forwarding plane, and not in userspace apps and signaling protocols like MP-iBG/Zebra/RSVP-TE, etc.), focusing on cleaning up the current implementation, and documenting along the way :) Remark: I have been working with the latest official release mpls 1.1. (1.172). Of course there is a lot to be done, but, as per Mantainers' : " Try to release a few ALPHA test versions to the net. Announce them onto the kernel channel and await results" Please, bear with me. I have spent only four days looking and changing the code :)) and I'm relatively new to linux kernel development. Objectives: ----------------- * Document. Write something like a developer's guide, documenting the whole MPLS subsystem, with short references to the Linux kernel networking core API (e.g. void dev_add_pack(struct packet_type *pt)). Describe not only each function and its arguments, but be more pedagogic (the lack of documentation of the existing implementation is an entry barrier). Explain the subsystem parts and draw execution paths/flows, etc. Most students are *afraid* of digging in kernel code. The ultimate goal is to have a platform with quagga (OSPF-TE/MP-iBGP) and the corresponding signaling protocols (RSVP-TE, CR-LDP,LMP), with advanced MPLS-TE features, like re-routing and protection switching, bu before that I'd like to work in order to make the linux-kernel implementation rock solid. Some docs have been done: http://perso.enst.fr/~casellas/mpls-linux/index.html More to come :) * Analysis of the existing implementation: can it be simplified? * Synchronize. Is anyone working on this? Let us not reinvent the wheel :) citing Dave Miller (should-fix). "Real serious use of IPSEC is hampered by lack of MPLS support. MPLS is a switching technology that works by switching based upon fixed length labels prepended to packets. Many people use this and IPSEC to implement VPNs over public networks, it is also used for things like traffic engineering. Anyways, an existing (crappy) implementation exists. I've almost completed a rewrite, I should have something in the tree next week." I'd like to know what comments does Mr. Miller have, and of course, if he is working on something similar. What does he consider crappy (the MII/MOI Radix Trees , the Opcode and instructions, code quality, lack of comments/documentation / etc???) * When porting the existing 2.4 implementation try to be as little intrusive as possible. We should make an effort not to modify the core parts of the system. Some things that we should think about: - Adding a new data field to net_device: it has been done in 2.4 (void* mpls_ptr) just like other subsystems. Maybe we can find a way by using only private data. - Forwarding Information Base / Routing Tables, etc. Again, the 2.4 version patches some core parts like include/net/ip.h, ip_fib and similar, adding new data fields to core structs. Fortunately some chunks are no longer needed, since they have been added to the mainstream kernel (e.g. ETH_P_MPLS_UC). Unfortunately, I'm not very aware of 2.6 changes (yet) and some chunks do not apply cleanly, e.g: --- linux-kernel/include/net/ip.h Sat Aug 24 00:22:09 2002 +++ mpls-kernel-fixes/include/net/ip.h Wed Nov 13 19:38:10 2002 @@ -162,9 +162,9 @@ static inline int ip_send(struct sk_buff *skb) - Side effects. chunks like --- linux-kernel/net/core/neighbour.c Sat Aug 24 00:22:26 2002 +++ mpls-kernel-fixes/net/core/neighbour.c Tue Nov 12 20:00:46 2002 @@ -952,7 +952,7 @@ 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); + neigh_hh_init(neigh, dst, skb->protocol); May have some serious side effects to other networking subsystems. In the following, I'd like to discuss and find a consensus. What has been done ------------------------ * I took the 2.4 1.127 patch and cleaned it up, formatted the code, and added comments in the parts that I did understand (and of course, introducing some new obscure and difficult to debug bugs in the way). * Ported the code to 2.6.0-bk22, latest version as of today. * The patch is *alpha* quality. In fact, it compiles, but kernel oopses on boot. I still don't know if it's my fault (definitely the most probable option) or because I just took the bk22 version in order to have the latest patches to the net subsystem. * THE PATCH REQUIRES intensive "peer review", I have made some arbitrary changes in the places that the 2.6.0 has changed with regard to 2.4 (for example, 2.6 has no "key" in the rtable struct). dst_entrys and so on... (James I would really appreciate it if you could take the time to review it) The actual patch is at: http://perso.enst.fr/~casellas/mpls-linux/linux-2.6.0-test9-bk22-mpls.diff Known issues and ToDOs ----------------------- * The current (2.4. 1.172) has been implemented as "built-in", and lacks all the "exit" functions. The MPLS subsystem MUST be modular, at least, with mpls.ko and mpls_tunnel.ko. Care must be taken in order to leave the kernel "clean" on module removal. * Some parts (updtaing statistics or mpls_input) could be implemented as BH (work queues or whatever). * The actual procfs implementation (cf. mpls_proc) should be moved to sysfs. * The Radix tree approach is cumbersome, I should review some of James' design decisions. The semantics of mpls_label, mpls_push_data mpls_key's are a little confusing. There is no exact "label entry" as described in the RFC. * The mpls_instruction{build, copy, offer, scratch,...} is complicated. There are some 200-line functions that should be split. * Some "key" variables are declared "unsigned int", which may break in other archs. Should use u_int32_t where appropriate. * Audit the code for SMP. * Some parts are not clear to me: - why do we copy structs around (e.g. in mpls_set_in_label_instructions)? memcpy(&mir,in,sizeof(struct mpls_instruction_req)); - What's the difference between mpls_del_in_label and __mpls_del_in_label? When do we call __mpls_del_in_label? - Why mpls_instruction_copy copies only the addresses and does not increase the refcount of data? (pointer aliasing) - struct net_device* mpls_tunnel_get_by_name (const char* name), it just iterates the list of netdevs, and returns a pointer,but it breaks the semantics of get/put. why there is no reference counting here? - A lot of code is just there to check if the arguments are NULL or not. Maybe we should fix the callers, and put some temporary BUG_ON(NULL == dev). For most functions, having NULL as an argument is not a valid option. * Some parts are still a little obscure, like copying around struct mpls_label just to obtain a key. * Rough corners :) if [ -r System.map ]; then /sbin/depmod -ae -F System.map 2.6.0-test9-bk22-mpls; fi WARNING: /lib/modules/2.6.0-test9-bk22-mpls/kernel/net/ipv4/netfilter/ipt_MPLS.ko needs unknown symbol mpls_output WARNING: /lib/modules/2.6.0-test9-bk22-mpls/kernel/net/ipv4/netfilter/ipt_MPLS.ko needs unknown symbol mpls_set_nexthop Of course, your comments are most welcome, and I plan to keep on working on it. Do not hesitate to contact me if you want me to keep you posted. Regards, Ramon // ------------------------------------------------------------------- // Ramon Casellas - GET/ENST/INFRES/RHD/A508 - cas...@in... // 37/39 rue Dareau 75014 Paris -- http://perso.enst.fr/~casellas |
|
From: <lis...@op...> - 2003-11-14 06:06:18
|
您好!
我是“呜哩嘛哩卡通大集合”店的小店主。小店新开张,东西不多,但价钱优惠。零售带批发的。
来看看吧。不买没关系。生意不做还可以做朋友的。
请点击http://www.eachnet.com/fu/shop/myshop.php?user_id=10984029
:)笑脸相迎哦!!
呜哩嘛哩敬上
<<---以上邮件内容与中资源网络及软件开发商无关--->>
-----------------------------------------------
中资源网络--域名先注册后付款;主机先开通后收费。
申请100M虚拟主机350元/年,送国际域名+5个信箱
http://www.263nic.com/
-----------------------------------------------
欢迎使用亿虎Email系列软件
下载地址: http://www.ehoosoft.com
定向邮箱搜索: 亿虎Email搜索大师
邮件群发特快: 亿虎Email邮差
病毒邮件克星: 亿虎Email安全大师
......
|
|
From: James R. L. <jl...@mi...> - 2003-11-14 03:01:24
|
On Thu, Nov 13, 2003 at 11:30:13PM +0100, Daniel Perez wrote: > Hello, > It's me again, I have a reed a few documentation, about DiffServ. > It seems possible to do QoS on mpls with it. It's good to hear that you did some reading. You are definitly on the right track. The first thing I would figure out how to do is to do normal QoS without MPLS. This means learning how to apply schedulers and mark packets. Once you have gotten that far, doing it with MPLS is just an incremental step of using an incoming label or EXP bits to do the marking. > I have understand that I need to use "iptables" to mark differents packets , the problem is that I really > don't know how to generate traffic with different class of service and how to configure a LER to make the > difference of the different class of service. As far as generating packets with differnt QoS or CoS, that is up to you. It could be as simple as saying all UDP traffic gets a lower priority then TCP traffic. You can use iptables for that. You could differentiate based on the destinations of the packets, you would use iproute2 for that. There are many packages out there for sending packets, as simple as TTCP and as complicated as packet gen. > > Maybe it's a stupide question, but I'm a novice in MPLS on Linux, and I really need help. > Please, if someone as an example of a configuration, could he please send me a solution. Unfortunatly I do not have an example. Like I said earlier, find an example of how to do QoS, CoS or DiffServ with IPv4 and then I can show you how to modify it to work with MPLS. If you want to look at the 'opcodes' for QoS, check out the readme in the mpls-linux/utils/README. Look at set_exp/exp2tc/exp2ds/nf2exp/tc2exp/ds2exp. -- James R. Leu jl...@mi... |