OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [net/] [core/] [dev_mcast.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 200 simons
/*
2
 *      Linux NET3:     Multicast List maintenance.
3
 *
4
 *      Authors:
5
 *              Tim Kordas <tjk@nostromo.eeap.cwru.edu>
6
 *              Richard Underwood <richard@wuzz.demon.co.uk>
7
 *
8
 *      Stir fried together from the IP multicast and CAP patches above
9
 *              Alan Cox <Alan.Cox@linux.org>
10
 *
11
 *      Fixes:
12
 *              Alan Cox        :       Update the device on a real delete
13
 *                                      rather than any time but...
14
 *              Alan Cox        :       IFF_ALLMULTI support.
15
 *              Alan Cox        :       New format set_multicast_list() calls.
16
 *
17
 *      This program is free software; you can redistribute it and/or
18
 *      modify it under the terms of the GNU General Public License
19
 *      as published by the Free Software Foundation; either version
20
 *      2 of the License, or (at your option) any later version.
21
 */
22
 
23
#include <asm/segment.h>
24
#include <asm/system.h>
25
#include <asm/bitops.h>
26
#include <linux/types.h>
27
#include <linux/kernel.h>
28
#include <linux/sched.h>
29
#include <linux/string.h>
30
#include <linux/mm.h>
31
#include <linux/socket.h>
32
#include <linux/sockios.h>
33
#include <linux/in.h>
34
#include <linux/errno.h>
35
#include <linux/interrupt.h>
36
#include <linux/if_ether.h>
37
#include <linux/inet.h>
38
#include <linux/netdevice.h>
39
#include <linux/etherdevice.h>
40
#include <net/ip.h>
41
#include <net/route.h>
42
#include <linux/skbuff.h>
43
#include <net/sock.h>
44
#include <net/arp.h>
45
 
46
 
47
/*
48
 *      Device multicast list maintenance. This knows about such little matters as promiscuous mode and
49
 *      converting from the list to the array the drivers use. At least until I fix the drivers up.
50
 *
51
 *      This is used both by IP and by the user level maintenance functions. Unlike BSD we maintain a usage count
52
 *      on a given multicast address so that a casual user application can add/delete multicasts used by protocols
53
 *      without doing damage to the protocols when it deletes the entries. It also helps IP as it tracks overlapping
54
 *      maps.
55
 */
56
 
57
 
58
/*
59
 *      Update the multicast list into the physical NIC controller.
60
 */
61
 
62
void dev_mc_upload(struct device *dev)
63
{
64
        /* Don't do anything till we up the interface
65
           [dev_open will call this function so the list will
66
            stay sane] */
67
 
68
        if(!(dev->flags&IFF_UP))
69
                return;
70
 
71
        /*
72
         *      Devices with no set multicast don't get set
73
         */
74
 
75
        if(dev->set_multicast_list==NULL)
76
                return;
77
 
78
        dev->set_multicast_list(dev);
79
}
80
 
81
/*
82
 *      Delete a device level multicast
83
 */
84
 
85
void dev_mc_delete(struct device *dev, void *addr, int alen, int all)
86
{
87
        struct dev_mc_list **dmi;
88
        for(dmi=&dev->mc_list;*dmi!=NULL;dmi=&(*dmi)->next)
89
        {
90
                if(memcmp((*dmi)->dmi_addr,addr,(*dmi)->dmi_addrlen)==0 && alen==(*dmi)->dmi_addrlen)
91
                {
92
                        struct dev_mc_list *tmp= *dmi;
93
                        if(--(*dmi)->dmi_users && !all)
94
                                return;
95
                        *dmi=(*dmi)->next;
96
                        dev->mc_count--;
97
                        kfree_s(tmp,sizeof(*tmp));
98
                        dev_mc_upload(dev);
99
                        return;
100
                }
101
        }
102
}
103
 
104
/*
105
 *      Add a device level multicast
106
 */
107
 
108
void dev_mc_add(struct device *dev, void *addr, int alen, int newonly)
109
{
110
        struct dev_mc_list *dmi;
111
        for(dmi=dev->mc_list;dmi!=NULL;dmi=dmi->next)
112
        {
113
                if(memcmp(dmi->dmi_addr,addr,dmi->dmi_addrlen)==0 && dmi->dmi_addrlen==alen)
114
                {
115
                        if(!newonly)
116
                                dmi->dmi_users++;
117
                        return;
118
                }
119
        }
120
        dmi=(struct dev_mc_list *)kmalloc(sizeof(*dmi),GFP_KERNEL);
121
        if(dmi==NULL)
122
                return; /* GFP_KERNEL so can't happen anyway */
123
        memcpy(dmi->dmi_addr, addr, alen);
124
        dmi->dmi_addrlen=alen;
125
        dmi->next=dev->mc_list;
126
        dmi->dmi_users=1;
127
        dev->mc_list=dmi;
128
        dev->mc_count++;
129
        dev_mc_upload(dev);
130
}
131
 
132
/*
133
 *      Discard multicast list when a device is downed
134
 */
135
 
136
void dev_mc_discard(struct device *dev)
137
{
138
        while(dev->mc_list!=NULL)
139
        {
140
                struct dev_mc_list *tmp=dev->mc_list;
141
                dev->mc_list=dev->mc_list->next;
142
                kfree_s(tmp,sizeof(*tmp));
143
        }
144
        dev->mc_count=0;
145
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.