Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
6addf306
Commit
6addf306
authored
Jan 10, 2017
by
Vikram Narayanan
Browse files
lcd/test_mod: Add a new module for nullnet driver
Signed-off-by:
Vikram Narayanan
<
vikram186@gmail.com
>
parent
f0a8ac84
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
lcd-domains/scripts/Kbuild.test_mods
View file @
6addf306
...
...
@@ -25,3 +25,4 @@ obj-m += bug/
obj-m += async_rpc/
obj-m += llvm_example/
obj-m += ioremap/
obj-m += nullnet/
lcd-domains/scripts/defaultconfig
View file @
6addf306
...
...
@@ -49,3 +49,7 @@ llvm_example/lcd isolated
ioremap/boot nonisolated
ioremap/lcd isolated
nullnet/boot nonisolated
nullnet/dummy_lcd isolated
nullnet/net_klcd nonisolated
lcd-domains/test_mods/nullnet/Kbuild
0 → 100644
View file @
6addf306
obj-$(LCD_CONFIG_BUILD_NULLNET_BOOT) += boot/
obj-$(LCD_CONFIG_BUILD_NULLNET_DUMMY_LCD) += dummy_lcd/
obj-$(LCD_CONFIG_BUILD_NULLNET_NET_KLCD) += net_klcd/
lcd-domains/test_mods/nullnet/boot/Kbuild
0 → 100644
View file @
6addf306
obj-m += lcd_test_mod_nullnet_boot.o
lcd_test_mod_nullnet_boot-y += main.o
ccflags-y += $(NONISOLATED_CFLAGS)
lcd-domains/test_mods/nullnet/boot/main.c
0 → 100644
View file @
6addf306
/*
* boot.c - non-isolated kernel module, does setup
* when fake minix and vfs are to be launched
* in isolated containers
*/
#include <lcd_config/pre_hook.h>
#include <liblcd/liblcd.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <lcd_config/post_hook.h>
static
int
boot_main
(
void
)
{
int
ret
;
cptr_t
net_chnl
;
cptr_t
net_chnl_domain_cptr
,
dummy_chnl_domain_cptr
;
cptr_t
net_lcd
,
dummy_lcd
;
struct
lcd_create_ctx
*
dummy_ctx
;
/*
* Enter lcd mode
*/
ret
=
lcd_enter
();
if
(
ret
)
{
LIBLCD_ERR
(
"lcd enter failed"
);
goto
fail1
;
}
/* ---------- Create vfs channel ---------- */
ret
=
lcd_create_sync_endpoint
(
&
net_chnl
);
if
(
ret
)
{
LIBLCD_ERR
(
"lcd create sync endpoint"
);
goto
fail2
;
}
/* ---------- Create LCDs ---------- */
ret
=
lcd_create_module_klcd
(
LCD_DIR
(
"nullnet/net_klcd"
),
"lcd_test_mod_nullnet_net_klcd"
,
&
net_lcd
);
if
(
ret
)
{
LIBLCD_ERR
(
"failed to create net klcd"
);
goto
fail3
;
}
ret
=
lcd_create_module_lcd
(
LCD_DIR
(
"nullnet/dummy_lcd"
),
"lcd_test_mod_nullnet_dummy_lcd"
,
&
dummy_lcd
,
&
dummy_ctx
);
if
(
ret
)
{
LIBLCD_ERR
(
"failed to create dummy lcd"
);
goto
fail4
;
}
/* ---------- Grant caps ---------- */
/*
ret = cptr_alloc(lcd_to_boot_cptr_cache(net_ctx),
&net_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("alloc cptr");
goto fail5;
}
ret = lcd_cap_grant(net_lcd, net_chnl, net_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail6;
} */
ret
=
cptr_alloc
(
lcd_to_boot_cptr_cache
(
dummy_ctx
),
&
dummy_chnl_domain_cptr
);
if
(
ret
)
{
LIBLCD_ERR
(
"alloc cptr"
);
goto
fail7
;
}
ret
=
lcd_cap_grant
(
dummy_lcd
,
net_chnl
,
dummy_chnl_domain_cptr
);
if
(
ret
)
{
LIBLCD_ERR
(
"grant"
);
goto
fail8
;
}
/* ---------- Set up boot info ---------- */
// lcd_to_boot_info(net_ctx)->cptrs[0] = net_chnl_domain_cptr;
net_chnl_domain_cptr
=
__cptr
(
3
);
ret
=
lcd_cap_grant
(
net_lcd
,
net_chnl
,
net_chnl_domain_cptr
);
if
(
ret
)
{
LIBLCD_ERR
(
"grant"
);
goto
fail6
;
}
lcd_to_boot_info
(
dummy_ctx
)
->
cptrs
[
0
]
=
dummy_chnl_domain_cptr
;
/* ---------- RUN! ---------- */
LIBLCD_MSG
(
"starting network..."
);
ret
=
lcd_run
(
net_lcd
);
if
(
ret
)
{
LIBLCD_ERR
(
"failed to start vfs lcd"
);
goto
fail9
;
}
/* Wait a few moments so vfs lcd has a chance to enter its
* dispatch loop. This is obviously a hack. You could use some
* kind of protocol to wait for the vfs to signal it is ready. */
//msleep(2000);
LIBLCD_MSG
(
"starting dummy ethernet..."
);
ret
=
lcd_run
(
dummy_lcd
);
if
(
ret
)
{
LIBLCD_ERR
(
"failed to start dummy lcd"
);
goto
fail10
;
}
/*
* Wait for 4 seconds
*/
msleep
(
4000
);
/*
* Tear everything down
*/
ret
=
0
;
goto
out
;
/* The destroy's will free up everything ... */
out:
fail10:
fail9:
fail8:
fail7:
fail6:
lcd_cap_delete
(
dummy_lcd
);
lcd_destroy_create_ctx
(
dummy_ctx
);
fail4:
lcd_cap_delete
(
net_lcd
);
fail3:
fail2:
lcd_exit
(
0
);
/* will free endpoints */
fail1:
return
ret
;
}
static
int
boot_init
(
void
)
{
int
ret
;
LCD_MAIN
({
ret
=
boot_main
();
});
return
ret
;
}
static
void
boot_exit
(
void
)
{
/* nothing to do */
}
module_init
(
boot_init
);
module_exit
(
boot_exit
);
lcd-domains/test_mods/nullnet/cap.c
0 → 100644
View file @
6addf306
/*
* cap.c
*
* cspace code for pmfs/vfs
*/
#include <lcd_config/pre_hook.h>
#include <libcap.h>
#include <liblcd/liblcd.h>
#include <linux/slab.h>
#include "glue_helper.h"
#include <lcd_config/post_hook.h>
/* ------------------------------------------------------------ */
static
struct
cap_type_system
*
glue_libcap_type_system
;
struct
type_ops_id
{
struct
cap_type_ops
ops
;
cap_type_t
libcap_type
;
};
enum
glue_type
{
GLUE_TYPE_NET_DEVICE
,
GLUE_TYPE_NET_DEVICE_OPS
,
GLUE_TYPE_NLATTR
,
GLUE_TYPE_RTNL_LINK_OPS
,
GLUE_TYPE_RTNL_LINK_STATS64
,
GLUE_TYPE_SK_BUFF
,
GLUE_NR_TYPES
,
};
static
int
dummy_func
(
struct
cspace
*
cspace
,
struct
cnode
*
cnode
,
void
*
object
)
{
return
0
;
}
static
struct
type_ops_id
glue_libcap_type_ops
[
GLUE_NR_TYPES
]
=
{
{
{
.
name
=
"struct net_device"
,
.
delete
=
dummy_func
,
.
revoke
=
dummy_func
,
}
},
{
{
.
name
=
"struct net_device_ops"
,
.
delete
=
dummy_func
,
.
revoke
=
dummy_func
,
}
},
{
{
.
name
=
"struct nlattr"
,
.
delete
=
dummy_func
,
.
revoke
=
dummy_func
,
}
},
{
{
.
name
=
"struct rtnl_link_ops"
,
.
delete
=
dummy_func
,
.
revoke
=
dummy_func
,
}
},
{
{
.
name
=
"struct rtnl_link_stats64"
,
.
delete
=
dummy_func
,
.
revoke
=
dummy_func
,
}
},
{
{
.
name
=
"struct sk_buff"
,
.
delete
=
dummy_func
,
.
revoke
=
dummy_func
,
}
},
};
int
glue_cap_init
(
void
)
{
int
ret
;
int
i
;
cap_type_t
libcap_type
;
/*
* Alloc and init microkernel type system
*/
ret
=
cap_type_system_alloc
(
&
glue_libcap_type_system
);
if
(
ret
)
{
LIBLCD_ERR
(
"alloc glue type system failed"
);
goto
fail1
;
}
ret
=
cap_type_system_init
(
glue_libcap_type_system
);
if
(
ret
)
{
LIBLCD_ERR
(
"init glue type system failed"
);
goto
fail2
;
}
/*
* Add types
*/
for
(
i
=
0
;
i
<
GLUE_NR_TYPES
;
i
++
)
{
libcap_type
=
cap_register_private_type
(
glue_libcap_type_system
,
0
,
&
glue_libcap_type_ops
[
i
].
ops
);
if
(
libcap_type
==
CAP_TYPE_ERR
)
{
LIBLCD_ERR
(
"failed to register glue cap type %s"
,
glue_libcap_type_ops
[
i
].
ops
.
name
);
ret
=
-
EIO
;
goto
fail3
;
}
glue_libcap_type_ops
[
i
].
libcap_type
=
libcap_type
;
}
return
0
;
fail3:
cap_type_system_destroy
(
glue_libcap_type_system
);
fail2:
cap_type_system_free
(
glue_libcap_type_system
);
glue_libcap_type_system
=
NULL
;
fail1:
return
ret
;
}
int
glue_cap_create
(
struct
glue_cspace
**
cspace_out
)
{
return
glue_cspace_alloc_init
(
glue_libcap_type_system
,
cspace_out
);
}
void
glue_cap_destroy
(
struct
glue_cspace
*
cspace
)
{
glue_cspace_destroy_free
(
cspace
);
}
void
glue_cap_exit
(
void
)
{
/*
* Destroy and free type system if necessary
*/
if
(
glue_libcap_type_system
)
{
cap_type_system_destroy
(
glue_libcap_type_system
);
cap_type_system_free
(
glue_libcap_type_system
);
glue_libcap_type_system
=
NULL
;
}
}
int
glue_cap_insert_net_device_type
(
struct
glue_cspace
*
cspace
,
struct
net_device_container
*
net_device_container
,
cptr_t
*
c_out
)
{
return
glue_cspace_insert
(
cspace
,
net_device_container
,
glue_libcap_type_ops
[
GLUE_TYPE_NET_DEVICE
].
libcap_type
,
c_out
);
}
int
glue_cap_insert_net_device_ops_type
(
struct
glue_cspace
*
cspace
,
struct
net_device_ops_container
*
net_device_ops_container
,
cptr_t
*
c_out
)
{
return
glue_cspace_insert
(
cspace
,
net_device_ops_container
,
glue_libcap_type_ops
[
GLUE_TYPE_NET_DEVICE_OPS
].
libcap_type
,
c_out
);
}
int
glue_cap_insert_nlattr_type
(
struct
glue_cspace
*
cspace
,
struct
nlattr_container
*
nlattr_container
,
cptr_t
*
c_out
)
{
return
glue_cspace_insert
(
cspace
,
nlattr_container
,
glue_libcap_type_ops
[
GLUE_TYPE_NLATTR
].
libcap_type
,
c_out
);
}
int
glue_cap_insert_rtnl_link_ops_type
(
struct
glue_cspace
*
cspace
,
struct
rtnl_link_ops_container
*
rtnl_link_ops_container
,
cptr_t
*
c_out
)
{
return
glue_cspace_insert
(
cspace
,
rtnl_link_ops_container
,
glue_libcap_type_ops
[
GLUE_TYPE_RTNL_LINK_OPS
].
libcap_type
,
c_out
);
}
int
glue_cap_insert_rtnl_link_stats64_type
(
struct
glue_cspace
*
cspace
,
struct
rtnl_link_stats64_container
*
rtnl_link_stats64_container
,
cptr_t
*
c_out
)
{
return
glue_cspace_insert
(
cspace
,
rtnl_link_stats64_container
,
glue_libcap_type_ops
[
GLUE_TYPE_RTNL_LINK_STATS64
].
libcap_type
,
c_out
);
}
int
glue_cap_insert_sk_buff_type
(
struct
glue_cspace
*
cspace
,
struct
sk_buff_container
*
sk_buff_container
,
cptr_t
*
c_out
)
{
return
glue_cspace_insert
(
cspace
,
sk_buff_container
,
glue_libcap_type_ops
[
GLUE_TYPE_SK_BUFF
].
libcap_type
,
c_out
);
}
int
glue_cap_lookup_net_device_type
(
struct
glue_cspace
*
cspace
,
cptr_t
c
,
struct
net_device_container
**
net_device_container
)
{
return
glue_cspace_lookup
(
cspace
,
c
,
glue_libcap_type_ops
[
GLUE_TYPE_NET_DEVICE
].
libcap_type
,
(
void
**
)
net_device_container
);
}
int
glue_cap_lookup_net_device_ops_type
(
struct
glue_cspace
*
cspace
,
cptr_t
c
,
struct
net_device_ops_container
**
net_device_ops_container
)
{
return
glue_cspace_lookup
(
cspace
,
c
,
glue_libcap_type_ops
[
GLUE_TYPE_NET_DEVICE_OPS
].
libcap_type
,
(
void
**
)
net_device_ops_container
);
}
int
glue_cap_lookup_nlattr_type
(
struct
glue_cspace
*
cspace
,
cptr_t
c
,
struct
nlattr_container
**
nlattr_container
)
{
return
glue_cspace_lookup
(
cspace
,
c
,
glue_libcap_type_ops
[
GLUE_TYPE_NLATTR
].
libcap_type
,
(
void
**
)
nlattr_container
);
}
int
glue_cap_lookup_rtnl_link_ops_type
(
struct
glue_cspace
*
cspace
,
cptr_t
c
,
struct
rtnl_link_ops_container
**
rtnl_link_ops_container
)
{
return
glue_cspace_lookup
(
cspace
,
c
,
glue_libcap_type_ops
[
GLUE_TYPE_RTNL_LINK_OPS
].
libcap_type
,
(
void
**
)
rtnl_link_ops_container
);
}
int
glue_cap_lookup_rtnl_link_stats64_type
(
struct
glue_cspace
*
cspace
,
cptr_t
c
,
struct
rtnl_link_stats64_container
**
rtnl_link_stats64_container
)
{
return
glue_cspace_lookup
(
cspace
,
c
,
glue_libcap_type_ops
[
GLUE_TYPE_RTNL_LINK_STATS64
].
libcap_type
,
(
void
**
)
rtnl_link_stats64_container
);
}
int
glue_cap_lookup_sk_buff_type
(
struct
glue_cspace
*
cspace
,
cptr_t
c
,
struct
sk_buff_container
**
sk_buff_container
)
{
return
glue_cspace_lookup
(
cspace
,
c
,
glue_libcap_type_ops
[
GLUE_TYPE_SK_BUFF
].
libcap_type
,
(
void
**
)
sk_buff_container
);
}
void
glue_cap_remove
(
struct
glue_cspace
*
cspace
,
cptr_t
c
)
{
glue_cspace_remove
(
cspace
,
c
);
}
lcd-domains/test_mods/nullnet/dummy_lcd/Kbuild
0 → 100644
View file @
6addf306
obj-m += lcd_test_mod_nullnet_dummy_lcd.o
lcd_test_mod_nullnet_dummy_lcd-y += main.o
# Original code
lcd_test_mod_nullnet_dummy_lcd-y += dummy.o
lcd_test_mod_nullnet_dummy_lcd-y += $(LIBLCD)
# glue code
lcd_test_mod_nullnet_dummy_lcd-y += $(addprefix glue/, nullnet_caller.o \
dispatch.o )
lcd_test_mod_nullnet_dummy_lcd-y += $(addprefix ../, cap.o)
ccflags-y += $(ISOLATED_CFLAGS)
lcd-domains/test_mods/nullnet/dummy_lcd/dummy.c
0 → 100644
View file @
6addf306
/* dummy.c: a dummy net driver
The purpose of this driver is to provide a device to point a
route through, but not to actually transmit packets.
Why? If you have a machine whose only connection is an occasional
PPP/SLIP/PLIP link, you can only connect to your own hostname
when the link is up. Otherwise you have to use localhost.
This isn't very consistent.
One solution is to set up a dummy link using PPP/SLIP/PLIP,
but this seems (to me) too much overhead for too little gain.
This driver provides a small alternative. Thus you can do
[when not running slip]
ifconfig dummy slip.addr.ess.here up
[to go to slip]
ifconfig dummy down
dip whatever
This was written by looking at Donald Becker's skeleton driver
and the loopback driver. I then threw away anything that didn't
apply! Thanks to Alan Cox for the key clue on what to do with
misguided packets.
Nick Holloway, 27th May 1994
[I tweaked this explanation a little but that's all]
Alan Cox, 30th May 1994
*/
#ifdef LCD_ISOLATE
#include <lcd_config/pre_hook.h>
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/rtnetlink.h>
#include <net/rtnetlink.h>
#include <linux/u64_stats_sync.h>
#include "../glue_helper.h"
#ifdef LCD_ISOLATE
#include <lcd_config/post_hook.h>
#endif
#define DRV_NAME "dummy"
#define DRV_VERSION "1.0"
static
int
numdummies
=
1
;
/* fake multicast ability */
static
void
set_multicast_list
(
struct
net_device
*
dev
)
{
}
struct
pcpu_dstats
{
u64
tx_packets
;
u64
tx_bytes
;
struct
u64_stats_sync
syncp
;
};
static
struct
rtnl_link_stats64
*
dummy_get_stats64
(
struct
net_device
*
dev
,
struct
rtnl_link_stats64
*
stats
)
{
//int i;
/* for_each_possible_cpu(i) {
const struct pcpu_dstats *dstats;
u64 tbytes, tpackets;
unsigned int start;
dstats = per_cpu_ptr(dev->dstats, i);
do {
start = u64_stats_fetch_begin_irq(&dstats->syncp);
tbytes = dstats->tx_bytes;
tpackets = dstats->tx_packets;
} while (u64_stats_fetch_retry_irq(&dstats->syncp, start));
stats->tx_bytes += tbytes;
stats->tx_packets += tpackets;
}*/
stats
->
tx_bytes
=
100
;
stats
->
tx_packets
=
0x5A5A
;
return
stats
;
}
static
netdev_tx_t
dummy_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
/* struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
u64_stats_update_begin(&dstats->syncp);
dstats->tx_packets++;
dstats->tx_bytes += skb->len;
u64_stats_update_end(&dstats->syncp);
*/
dev_kfree_skb
(
skb
);
return
NETDEV_TX_OK
;
}
static
int
dummy_dev_init
(
struct
net_device
*
dev
)
{
/* dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
if (!dev->dstats)
return -ENOMEM;
*/
return
0
;
}
static
void
dummy_dev_uninit
(
struct
net_device
*
dev
)
{
// free_percpu(dev->dstats);
}
static
int
dummy_change_carrier
(
struct
net_device
*
dev
,
bool
new_carrier
)
{
if
(
new_carrier
)
netif_carrier_on
(
dev
);