1.调度器的概述
多任务操作系统分为非抢占式多任务和抢占式多任务。与大多数现代操作系统一样,Linux采用的是抢占式多任务模式。这表示对CPU的占用时间由操作系统决定的,具体为操作系统中的调度器。调度器决定了什么时候停止一个进程以便让其他进程有机会运行,同时挑选出一个其他的进程开始运行。
2.调度策略
在Linux上调度策略决定了调度器是如何选择一个新进程的时间。调度策略与进程的类型有关,内核现有的调度策略如下:
#define SCHED_NORMAL 0#define SCHED_FIFO 1#define SCHED_RR 2#define SCHED_BATCH 3/* SCHED_ISO: reserved but not implemented yet */#define SCHED_IDLE 5。
0: 默认的调度策略,针对的是普通进程。
1:针对实时进程的先进先出调度。适合对时间性要求比较高但每次运行时间比较短的进程。
2:针对的是实时进程的时间片轮转调度。适合每次运行时间比较长得进程。
3:针对批处理进程的调度,适合那些非交互性且对cpu使用密集的进程。
SCHED_ISO:是内核的一个预留字段,目前还没有使用。
5:适用于优先级较低的后台进程。
注:每个进程的调度策略保存在进程描述符task_struct中的policy字段。
3.调度器中的机制
内核引入调度类(struct sched_class)说明了调度器应该具有哪些功能。内核中每种调度策略都有该调度类的一个实例。(比如:基于公平调度类为:fair_sched_class,基于实时进程的调度类实例为:rt_sched_class),该实例也是针对每种调度策略的具体实现。调度类封装了不同调度策略的具体实现,屏蔽了各种调度策略的细节实现。
调度器核心函数schedule()只需要调用调度类中的接口,完成进程的调度,完全不需要考虑调度策略的具体实现。调度类连接了调度函数和具体的调度策略。
武特师兄关于sche_class和sche_entity的解释,一语中的。
调度类就是代表的各种调度策略,调度实体就是调度单位,这个实体通常是一个进程,但是自从引入了cgroup后,这个调度实体可能就不是一个进程了,而是一个组。
4.schedule()函数
linux 支持两种类型的进程调度,实时进程和普通进程。实时进程采用SCHED_FIFO 和SCHED_RR调度策略,普通进程采用SCHED_NORMAL策略。
preempt_disable():禁止内核抢占。
cpu_rq():获取当前cpu对应的就绪队列。
prev = rq->curr;获取当前进程的描述符prev。
switch_count = &prev->nivcsw;获取当前进程的切换次数。
update_rq_clock() :更新就绪队列上的时钟。
clear_tsk_need_resched()清楚当前进程prev的重新调度标志。
deactive_task():将当前进程从就绪队列中删除。
put_prev_task() :将当前进程重新放入就绪队列。
pick_next_task():在就绪队列中挑选下一个将被执行的进程。
context_switch():进行prev和next两个进程的切换。具体的切换代码与体系架构有关,在switch_to()中通过一段汇编代码实现。
post_schedule():进行进程切换后的后期处理工作。
5.pick_next_task函数。
选择下一个将要被执行的进程无疑是一个很重要的过程,我们来看一下内核中代码的实现。
对以下这段代码说明:
1.当rq中的运行队列的个数(nr_running)和cfs中的nr_runing相等的时候,表示现在所有的都是普通进程,这时候就会调用cfs算法中的pick_next_task(其实是pick_next_task_fair函数),当不相等的时候,则调用sched_class_highest(这是一个宏,指向的是实时进程),这下面的这个for(;;)循环中,首先是会在实时进程中选取要调度的程序(p = class->pick_next_task(rq);)。如果没有选取到,会执行class=class->next;在class这个链表中有三种类型(fair,idle,rt).也就是说会调用到下一个调度类。
static inline struct task_struct *pick_next_task(struct rq *rq){ const struct sched_class *class; struct task_struct *p; /*。
* Optimization: we know that if all tasks are in。
* the fair class we can call that function directly:。
*///基于公平调度的普通进程。
if (likely(rq->nr_running == rq->cfs.nr_running)) {。
p = fair_sched_class.pick_next_task(rq); if (likely(p)) return p;。
}//基于实时调度的实时进程。
class = sched_class_highest; for ( ; ; ) {。
p = class->pick_next_task(rq); //实时进程的类。
if (p) return p; /*。
* Will never be NULL as the idle class always。
* returns a non-NULL p:。
*/
class = class->next; //rt->next = fair; fair->next = idle。
}
在这段代码中体现了Linux所支持的两种类型的进程,实时进程和普通进程。回顾下:实时进程可以采用SCHED_FIFO 和SCHED_RR调度策略,普通进程采用SCHED_NORMAL调度策略。
在这里首先说明一个结构体struct rq,这个结构体是调度器管理可运行状态进程的最主要的数据结构。每个cpu上都有一个可运行的就绪队列。刚才在pick_next_task函数中看到了在选择下一个将要被执行的进程时实际上用的是struct rq上的普通进程的调度或者实时进程的调度,那么具体是如何调度的呢?在实时调度中,为了实现O(1)的调度算法,内核为每个优先级维护一个运行队列和一个DECLARE_BITMAP,内核根据DECLARE_BITMAP的bit数值找出非空的最高级优先队列的编号,从而可以从非空的最高级优先队列中取出进程进行运行。
我们来看下内核的实现
struct rt_prio_array {。
DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */。
struct list_head queue[MAX_RT_PRIO];。
};
数组queue[i]里面存放的是优先级为i的进程队列的链表头。在结构体rt_prio_array 中有一个重要的数据构DECLARE_BITMAP,它在内核中的第一如下:
define DECLARE_BITMAP(name,bits) \。
unsigned long name[BITS_TO_LONGS(bits)]。
5.1对于实时进程的O(1)算法。
这个数据是用来作为进程队列queue[MAX_PRIO]的索引位图。bitmap中的每一位与queue[i]对应,当queue[i]的进程队列不为空时,Bitmap的相应位就为1,否则为0,这样就只需要通过汇编指令从进程优先级由高到低的方向找到第一个为1的位置,则这个位置就是就绪队列中最高的优先级(函数sched_find_first_bit()就是用来实现该目的的)。那么queue[index]->next就是要找的候选进程。
如果还是不懂,那就来看两个图
注:在每个队列上的任务一般基于先进先出的原则进行调度(并且为每个进程分配时间片)
在内核中的实现为:
static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq, struct rt_rq *rt_rq){ struct rt_prio_array *array = &rt_rq->active; struct sched_rt_entity *next = NULL; struct list_head *queue; int idx;。
idx = sched_find_first_bit(array->bitmap); //找到优先级最高的位。
BUG_ON(idx >= MAX_RT_PRIO); queue = array->queue + idx; //然后找到对应的queue的起始地址。
next = list_entry(queue->next, struct sched_rt_entity, run_list); //按先进先出拿任务。
return next;。
那么当同一优先级的任务比较多的时候,内核会根据。
位图:
将对应的位置为1,每次取出最大的被置为1的位,表示优先级最高:
5.2 关于普通进程的CFS算法:
我们知道,普通进程在选取下一个需要被调度的进程时,是调用的pick_next_task_fair函数。在这个函数中是以调度实体为单位进行调度的。其最主要的函数是:pick_next_entity,在这个函数中会调用wakeup_preempt_entity函数,这个函数的主要作用是根据进程的虚拟时间以及权重的结算进程的粒度,以判断其是否需要抢占。看一下内核是怎么实现的:
wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)。
s64 gran, vdiff = curr->vruntime - se->vruntime;//计算两个虚拟时间差//如果se的虚拟时间比curr还大,说明本该curr执行,无需抢占。
if (vdiff <= 0) return -1;。
gran = wakeup_gran(curr, se); if (vdiff > gran) return 1; return 0;。
gran为需要抢占的时间差,只有两个时间差大于需要抢占的时间差,才需要抢占,这里避免太频繁的抢占。
wakeup_gran(struct sched_entity *curr, struct sched_entity *se)。
unsigned long gran = sysctl_sched_wakeup_granularity; if (cfs_rq_of(curr)->curr && sched_feat(ADAPTIVE_GRAN))。
gran = adaptive_gran(curr, se);。
/*
* Since its curr running now, convert the gran from real-time。
* to virtual-time in his units.。
*/ if (sched_feat(ASYM_GRAN)) {。
/*
* By using 'se' instead of 'curr' we penalize light tasks, so。
* they get preempted easier. That is, if 'se' < 'curr' then。
* the resulting gran will be larger, therefore penalizing the。
* lighter, if otoh 'se' > 'curr' then the resulting gran will。
* be smaller, again penalizing the lighter task.。
*
* This is especially important for buddies when the leftmost。
* task is higher priority than the buddy.。
*/ if (unlikely(se->load.weight != NICE_0_LOAD))。
gran = calc_delta_fair(gran, se);。
} else { if (unlikely(curr->load.weight != NICE_0_LOAD))。
gran = calc_delta_fair(gran, curr);。
} return gran;。
6.调度中的nice值
首先需要明确的是:nice的值不是进程的优先级,他们不是一个概念,但是进程的Nice值会影响到进程的优先级的变化。
通过命令ps -el可以看到进程的nice值为NI列。PRI表示的是进程的优先级,其实进程的优先级只是一个整数,它是调度器选择进程运行的基础。
普通进程有:静态优先级和动态优先级。
静态优先级:之所有称为静态优先级是因为它不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改,静态优先级用进程描述符中的static_prio来表示。在内核中/kernel/sched.c中,nice和静态优先级的关系为:
#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20)。
#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)。
动态优先级:调度程序通过增加或者减小进程静态优先级的值来奖励IO小的进程或者惩罚cpu消耗型的进程。调整后的优先级称为动态优先级。在进程描述中用prio来表示,通常所说的优先级指的是动态优先级。
由上面分析可知,我们可以通过系统调用nice函数来改变进程的优先级。
#include <stdlib.h>#include <stdio.h>#include <math.h>#include <unistd.h>#include <sys/time.h>#define JMAX (400*100000)#define GET_ELAPSED_TIME(tv1,tv2) ( \。
(double)( (tv2.tv_sec - tv1.tv_sec) \。
+ .000001 * (tv2.tv_usec - tv1.tv_usec)))//做一个延迟的计算double do_something (void){ int j; double x = 0.0; struct timeval tv1, tv2;。
gettimeofday (&tv1, NULL);//获取时区。
for (j = 0; j < JMAX; j++)。
x += 1.0 / (exp ((1 + x * x) / (2 + x * x)));。
gettimeofday (&tv2, NULL); return GET_ELAPSED_TIME (tv1, tv2);//求差值}int main (int argc, char *argv[]){ int niceval = 0, nsched; /* for kernels less than 2.6.21, this is HZ。
for tickless kernels this must be the MHZ rate。
e.g, for 2.6 GZ scale = 2600000000 */。
long scale = 1000; long ticks_cpu, ticks_sleep; pid_t pid;。
FILE *fp; char fname[256]; double elapsed_time, timeslice, t_cpu, t_sleep; if (argc > 1)。
niceval = atoi (argv[1]);。
pid = getpid (); if (argc > 2)。
scale = atoi (argv[2]); /* give a chance for other tasks to queue up */。
sleep (3); sprintf (fname, "/proc/%d/schedstat", pid);//读取进程的调度状态。
/*
在schedstat中的数字是什么意思呢?:
*/
/* printf ("Fname = %s\n", fname); */。
if (!(fp = fopen (fname, "r"))) { printf ("Failed to open stat file\n"); exit (-1);。
} //nice系统调用。
if (nice (niceval) == -1 && niceval != -1) { printf ("Failed to set nice to %d\n", niceval); exit (-1);。
}
elapsed_time = do_something ();//for 循环执行了多长时间。
fscanf (fp, "%ld %ld %d", &ticks_cpu, &ticks_sleep, &nsched);//nsched表示调度的次数。
t_cpu = (float)ticks_cpu / scale;//震动的次数除以1000,就是时间。
t_sleep = (float)ticks_sleep / scale;。
timeslice = t_cpu / (double)nsched;//除以调度的次数,就是每次调度的时间(时间片)
printf ("\nnice=%3d time=%8g secs pid=%5d"。
" t_cpu=%8g t_sleep=%8g nsched=%5d"。
" avg timeslice = %8g\n",。
niceval, elapsed_time, pid, t_cpu, t_sleep, nsched, timeslice);。
fclose (fp); exit (0);。
说明: 首先说明的是/proc/[pid]/schedstat:在这个文件下放着3个变量,他们分别代表什么意思呢?
第一个:该进程拥有的cpu的时间。
第二个:在对列上的等待时间,即睡眠时间。
第三个:被调度的次数
由结果可以看出当nice的值越小的时候,其睡眠时间越短,则表示其优先级升高了。
7.关于获取和设置优先级的系统调用:sched_getscheduler()和sched_setscheduler。
#include <sched.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#define DEATH(mess) { perror(mess); exit(errno); }void printpolicy (int policy){ /* SCHED_NORMAL = SCHED_OTHER in user-space */。
if (policy == SCHED_OTHER) printf ("policy = SCHED_OTHER = %d\n", policy); if (policy == SCHED_FIFO) printf ("policy = SCHED_FIFO = %d\n", policy); if (policy == SCHED_RR) printf ("policy = SCHED_RR = %d\n", policy);。
}int main (int argc, char **argv){ int policy; struct sched_param p; /* obtain current scheduling policy for this process */。
//获取进程调度的策略
policy = sched_getscheduler (0);。
printpolicy (policy); /* reset scheduling policy */。
printf ("\nTrying sched_setscheduler...\n");。
policy = SCHED_FIFO;。
printpolicy (policy);。
p.sched_priority = 50; //设置优先级为50。
if (sched_setscheduler (0, policy, &p))。
DEATH ("sched_setscheduler:"); printf ("p.sched_priority = %d\n", p.sched_priority); exit (0);。
输出结果:
[root@wang schedule]# ./get_schedule_policy policy = SCHED_OTHER = 0。
Trying sched_setscheduler...。
policy = SCHED_FIFO = 1。
p.sched_priority = 50。
可以看出进程的优先级已经被改变。
SCHED_E_TRIGGER_NOT_FOUND。
0x80041309
未找到任务触发。尝试编辑任务触发器。
SCHED_E_TASK_NOT_READY。
0x8004130A
一个或多个执行这项任务所需的属性尚未设置。
SCHED_E_TASK_NOT_RUNNING。
0x8004130B
有没有任务运行实例。
SCHED_E_SERVICE_NOT_INSTALLED。
0x8004130C
Task Scheduler服务没有安装这台计算机上。
SCHED_E_CANNOT_OPEN_TASK。
0x8004130D
任务对象不能被打开。
SCHED_E_INVALID_TASK。
0x8004130E
对象是无效的任务对象,或者是不是一个任务对象。
SCHED_E_ACCOUNT_INFORMATION_NOT_SET。
0x8004130F
没有帐户信息,可以发现在任务计划程序安全数据库的任务表示。设置任务帐户信息。
SCHED_E_ACCOUNT_NAME_NOT_FOUND。
0x80041310
无法建立指定的帐户存在。设置任务帐户信息。
SCHED_E_ACCOUNT_DBASE_CORRUPT。
0x80041311
腐败被检测的任务计划程序安全数据库;数据库已复位。
SCHED_E_NO_SECURITY_SERVICES。
0x80041312
仅适用于Windows NT的工作排程器安全服务。
SCHED_E_UNKNOWN_OBJECT_VERSION。
0x80041313
任务对象版本是不受支持或无效。
SCHED_E_UNSUPPORTED_ACCOUNT_OPTION。
0x80041314
任务已配置帐户设置和运行时选项不受支持的组合。
SCHED_E_SERVICE_NOT_RUNNING。
0x80041315
任务计划程序服务没有运行。启动Task Scheduler服务。
SCHED_E_UNEXPECTEDNODE。
0x80041316
任务XML包含一个意想不到的节点。
SCHED_E_NAMESPACE。
0x80041317
任务XML包含从一个意想不到的命名空间的元素或属性。
SCHED_E_INVALIDVALUE。
0x80041318
任务XML包含一个格式不正确或超出范围的值。
SCHED_E_MISSINGNODE。
0x80041319
任务XML缺少一个必需的元素或属性。
SCHED_E_MALFORMEDXML。
0x8004131A
任务的XML格式不正确。
SCHED_S_SOME_TRIGGERS_FAILED。
0x0004131B
注册任务,但并非所有指定触发器将启动任务。
SCHED_S_BATCH_LOGON_PROBLEM。
0x0004131C
注册任务,但可能无法启动。必须启用的任务主要为批量登录权限。
SCHED_E_TOO_MANY_NODES。
0x8004131D
任务XML包含了太多的相同类型的节点。
SCHED_E_PAST_END_BOUNDARY。
0x8004131E
任务不能启动触发后的最终边界。
SCHED_E_ALREADY_RUNNING。
0x8004131F
这项任务的一个实例已在运行。
SCHED_E_USER_NOT_LOGGED_ON。
0x80041320
该任务将无法运行,因为用户没有登录。
SCHED_E_INVALID_TASK_HASH。
0x80041321
任务映像已损坏或已被篡改。
SCHED_E_SERVICE_NOT_AVAILABLE。
0x80041322
Task Scheduler服务不可用。
SCHED_E_SERVICE_TOO_BUSY。
0x80041323
Task Scheduler服务正忙,无法处理请求。请稍后再试。
SCHED_E_TASK_ATTEMPTED。
0x80041324
Task Scheduler服务试图运行任务,但任务没有运行,由于任务定义中的制约因素之一。
SCHED_S_TASK_QUEUED。
0x00041325
Task Scheduler服务已指示要运行的任务。
SCHED_E_TASK_DISABLED。
0x80041326
被禁用的任务。
SCHED_E_TASK_NOT_V1_COMPAT。
0x80041327
任务属性与早期版本的Windows不兼容。
SCHED_E_START_ON_DEMAND。
0x80041328
任务设置不允许任务需求开始。
确认
创建一个用户的任务引擎无法启动,并确保该事件300,这表明,本次会议开始,成功,在的Microsoft-Windows-TaskScheduler/Operational事件日志记录的任务。
要定义一个任务,并注册一个任务:
1。在开始搜索框中,点击开始按钮,并键入 工作排程 。
2。选择 任务调度 程序启动工作排程。
3。单击“ 创建任务。
4。在“ 常规 “选项卡上,定义一个任务的名称。在“ 触发器 “选项卡上,添加一个触发任务。在“ 操作 “选项卡,定义行动的任务。
5。点击“确定”,验证,创建任务时,没有错误报告。
6。选择新创建的任务和验证历史 “选项卡上,不会有任何部分注册失败的任务。
以核实该事件是在工作排程事件日志:
1。在“ 开始搜索 “框中,单击“ 开始 “按钮,事件查看器 类型 。
2。选择 启动事件查看器的 事件查看器程序。
3。事件日志找到扩大的Microsoft-Windows-TaskScheduler/Operational的应用程序和服务日志文件夹,扩大Microsoft文件夹,Windows 文件夹中的扩大 ,扩大TaskScheduler文件夹,然后单击“ 运行的事件日志。
4。检查事件日志300。
楼主,你好哈
脚本配置如下
路由器:
sys
sysname GateWay。
interface g0/0
des TO_CoreSwitch-G0/24。
ip add 192.168.1.1 29。
quit
ip route-static 192.168.10.0 24 192.168.1.2。
ip route-static 192.168.20.0 24 192.168.1.2。
核心交换机
sys
sysname CoreSwitch。
vlan batch 10 20 100。
inter vlan 100
des TO_GateWay-G0/0。
ip add 192.168.1.2 29。
quit
inter vlan 10
ip add 192.168.10.254 24。
quit
inter vlan 20
ip add 192.168.20.254 24。
quit
inter g0/24
des TO_GateWay。
port link-type access。
port default vlan 100。
quit
inter g0/22
des TO_SwitchA。
port link-type trunk。
port trunk all vlan 10 20。
undo port trunk all vlan 1。
quit
inter g0/23
des TO_SwitchB。
port link-type trunk。
port trunk all vlan 10 20。
undo port trunk all vlan 1。
quit
接入交换机
sys
sysname SwitchA。
vlan batch 10 20。
inter g0/24
port link-type trunk。
port trunk all vlan 10 20。
undo port trunk vlan 1。
inter g0/1
port link-type access。
port default vlan 10。
quit
inter g0/2
port link-type access。
port default vlan 20。
quit
我们没用过你说的TPlink的路由器,我就用华为的低端路由器代替吧。
设备配置如下:
AR1:
[V200R003C00]
sysname AR1
snmp-agent local-engineid 800007DB03000000000000。
snmp-agent
clock timezone China-Standard-Time minus 08:00:00。
portal local-server load portalpage.zip。
drop illegal-mac alarm。
vlan batch 10
set cpu-usage threshold 80 restore 75。
dhcp enable
aaa
authentication-scheme default。
authorization-scheme default。
accounting-scheme default。
domain default
domain default_admin。
local-user admin password cipher %$%$K8m.Nt84DZ}e#<0`8bmE3Uw}%$%$。
local-user admin service-type http。
firewall zone Local。
priority 15
interface Vlanif10。
ip address 192.168.10.1 255.255.255.0。
dhcp select interface。
interface Ethernet0/0/0。
port link-type access。
port default vlan 10。
interface Ethernet0/0/1。
interface Ethernet0/0/2。
interface Ethernet0/0/3。
interface Ethernet0/0/4。
interface Ethernet0/0/5。
interface Ethernet0/0/6。
interface Ethernet0/0/7。
interface GigabitEthernet0/0/0。
interface GigabitEthernet0/0/1。
interface NULL0。
interface LoopBack0。
ip address 1.1.1.1 255.255.255.255。
user-interface con 0。
authentication-mode password。
user-interface vty 0 4。
user-interface vty 16 20。
wlan ac
return
AR2:
[V200R003C00]
sysname AR2
snmp-agent local-engineid 800007DB03000000000000。
snmp-agent
clock timezone China-Standard-Time minus 08:00:00。
portal local-server load portalpage.zip。
drop illegal-mac alarm。
vlan batch 20
set cpu-usage threshold 80 restore 75。
dhcp enable
aaa
authentication-scheme default。
authorization-scheme default。
accounting-scheme default。
domain default
domain default_admin。
local-user admin password cipher %$%$K8m.Nt84DZ}e#<0`8bmE3Uw}%$%$。
local-user admin service-type http。
firewall zone Local。
priority 15
interface Vlanif20。
ip address 192.168.20.1 255.255.255.0。
dhcp select interface。
interface Ethernet0/0/0。
port link-type access。
port default vlan 20。
interface Ethernet0/0/1。
interface Ethernet0/0/2。
interface Ethernet0/0/3。
interface Ethernet0/0/4。
interface Ethernet0/0/5。
interface Ethernet0/0/6。
interface Ethernet0/0/7。
interface GigabitEthernet0/0/0。
interface GigabitEthernet0/0/1。
interface NULL0。
interface LoopBack0。
ip address 2.2.2.2 255.255.255.255。
user-interface con 0。
authentication-mode password。
user-interface vty 0 4。
user-interface vty 16 20。
wlan ac
return
LSW1:
sysname SW
vlan batch 10 20。
cluster enable
ntdp enable
ndp enable
drop illegal-mac alarm。
diffserv domain default。
drop-profile default。
aaa
authentication-scheme default。
authorization-scheme default。
accounting-scheme default。
domain default
domain default_admin。
local-user admin password simple admin。
local-user admin service-type http。
interface Vlanif1。
interface MEth0/0/1。
interface GigabitEthernet0/0/1。
port link-type access。
port default vlan 10。
interface GigabitEthernet0/0/2。
port link-type access。
port default vlan 20。
interface GigabitEthernet0/0/3。
port link-type access。
port default vlan 10。
interface GigabitEthernet0/0/4。
port link-type access。
port default vlan 20。
interface GigabitEthernet0/0/5。
interface GigabitEthernet0/0/6。
interface GigabitEthernet0/0/7。
interface GigabitEthernet0/0/8。
interface GigabitEthernet0/0/9。
interface GigabitEthernet0/0/10。
interface GigabitEthernet0/0/11。
interface GigabitEthernet0/0/12。
interface GigabitEthernet0/0/13。
interface GigabitEthernet0/0/14。
interface GigabitEthernet0/0/15。
interface GigabitEthernet0/0/16。
interface GigabitEthernet0/0/17。
interface GigabitEthernet0/0/18。
interface GigabitEthernet0/0/19。
interface GigabitEthernet0/0/20。
interface GigabitEthernet0/0/21。
interface GigabitEthernet0/0/22。
interface GigabitEthernet0/0/23。
interface GigabitEthernet0/0/24。
interface NULL0。
user-interface con 0。
user-interface vty 0 4。
return
1、设备组网:2台电脑分别属于VLAN10和VLAN20,一台华为AR2220路由器和一台S5700交换机。
2、配置两台PC的IP地址。PC1为下图。
2、PC2为下图。
3、在交换机中进行如下配置:1).连接两台PC机的端口配置为access模式,且分别属于对应的VLAN;2).连接路由器的端口配置为trunk模式,且允许PC机的VLAN通过。
命令:
创建VLAN10和VLAN20:vlan batch 10 20。
GE 0/0/2:
interface GigabitEthernet 0/0/2。
port link-type access。
port default vlan 10。
quit
GE 0/0/3:
interface GigabitEthernet 0/0/3。
port link-type access。
port default vlan 20。
quit
GE 0/0/1:
interface GigabitEthernet 0/0/1。
port link-type trunk。
port trunk allow-pass vlan 10 20。
4、在路由器中将一个物理接口配置两个逻辑子接口,两个子接口都开启802.1q,且分别属于不同的VLAN。
命令:
子接口1:
interface GigabitEthernet 0/0/1.1。
dot1q termination vid 10。
ip address 10.0.10.1 255.255.255.0。
arp broadcast enable。
quit
子接口2:
interface GigabitEthernet 0/0/1.2。
dot1q termination vid 20。
ip address 10.0.20.1 255.255.255.0。
arp broadcast enable。
quit
5、当配置完成后,可以分别在PC1和PC2检查相互之间可以进行通信。